mirror of
https://github.com/gabime/spdlog.git
synced 2024-12-26 02:21:34 +08:00
astyle
This commit is contained in:
parent
5a8cecdfb6
commit
0c276beaaf
@ -216,7 +216,8 @@ inline spdlog::details::async_log_helper::async_log_helper(
|
|||||||
// and wait for it to finish gracefully
|
// and wait for it to finish gracefully
|
||||||
inline spdlog::details::async_log_helper::~async_log_helper()
|
inline spdlog::details::async_log_helper::~async_log_helper()
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
push_msg(async_msg(async_msg_type::terminate));
|
push_msg(async_msg(async_msg_type::terminate));
|
||||||
_worker_thread.join();
|
_worker_thread.join();
|
||||||
}
|
}
|
||||||
@ -234,13 +235,16 @@ inline void spdlog::details::async_log_helper::log(const details::log_msg& msg)
|
|||||||
|
|
||||||
inline void spdlog::details::async_log_helper::push_msg(details::async_log_helper::async_msg&& new_msg)
|
inline void spdlog::details::async_log_helper::push_msg(details::async_log_helper::async_msg&& new_msg)
|
||||||
{
|
{
|
||||||
if (!_q.enqueue(std::move(new_msg)) && _overflow_policy != async_overflow_policy::discard_log_msg) {
|
if (!_q.enqueue(std::move(new_msg)) && _overflow_policy != async_overflow_policy::discard_log_msg)
|
||||||
|
{
|
||||||
auto last_op_time = details::os::now();
|
auto last_op_time = details::os::now();
|
||||||
auto now = last_op_time;
|
auto now = last_op_time;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
now = details::os::now();
|
now = details::os::now();
|
||||||
sleep_or_yield(now, last_op_time);
|
sleep_or_yield(now, last_op_time);
|
||||||
} while (!_q.enqueue(std::move(new_msg)));
|
}
|
||||||
|
while (!_q.enqueue(std::move(new_msg)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,14 +262,18 @@ inline void spdlog::details::async_log_helper::worker_loop()
|
|||||||
auto last_pop = details::os::now();
|
auto last_pop = details::os::now();
|
||||||
auto last_flush = last_pop;
|
auto last_flush = last_pop;
|
||||||
auto active = true;
|
auto active = true;
|
||||||
while (active) {
|
while (active)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
active = process_next_msg(last_pop, last_flush);
|
active = process_next_msg(last_pop, last_flush);
|
||||||
}
|
}
|
||||||
catch (const std::exception &ex) {
|
catch (const std::exception &ex)
|
||||||
|
{
|
||||||
_err_handler(ex.what());
|
_err_handler(ex.what());
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...)
|
||||||
|
{
|
||||||
_err_handler("Unknown exception");
|
_err_handler("Unknown exception");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,9 +288,11 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
|
|||||||
{
|
{
|
||||||
async_msg incoming_async_msg;
|
async_msg incoming_async_msg;
|
||||||
|
|
||||||
if (_q.dequeue(incoming_async_msg)) {
|
if (_q.dequeue(incoming_async_msg))
|
||||||
|
{
|
||||||
last_pop = details::os::now();
|
last_pop = details::os::now();
|
||||||
switch (incoming_async_msg.msg_type) {
|
switch (incoming_async_msg.msg_type)
|
||||||
|
{
|
||||||
case async_msg_type::flush:
|
case async_msg_type::flush:
|
||||||
_flush_requested = true;
|
_flush_requested = true;
|
||||||
break;
|
break;
|
||||||
@ -296,8 +306,10 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
|
|||||||
log_msg incoming_log_msg;
|
log_msg incoming_log_msg;
|
||||||
incoming_async_msg.fill_log_msg(incoming_log_msg);
|
incoming_async_msg.fill_log_msg(incoming_log_msg);
|
||||||
_formatter->format(incoming_log_msg);
|
_formatter->format(incoming_log_msg);
|
||||||
for (auto &s : _sinks) {
|
for (auto &s : _sinks)
|
||||||
if (s->should_log(incoming_log_msg.level)) {
|
{
|
||||||
|
if (s->should_log(incoming_log_msg.level))
|
||||||
|
{
|
||||||
s->log(incoming_log_msg);
|
s->log(incoming_log_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,7 +319,8 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
|
|||||||
|
|
||||||
// Handle empty queue..
|
// Handle empty queue..
|
||||||
// This is the only place where the queue can terminate or flush to avoid losing messages already in the queue
|
// This is the only place where the queue can terminate or flush to avoid losing messages already in the queue
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
auto now = details::os::now();
|
auto now = details::os::now();
|
||||||
handle_flush_interval(now, last_flush);
|
handle_flush_interval(now, last_flush);
|
||||||
sleep_or_yield(now, last_pop);
|
sleep_or_yield(now, last_pop);
|
||||||
@ -319,7 +332,8 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
|
|||||||
inline void spdlog::details::async_log_helper::handle_flush_interval(log_clock::time_point& now, log_clock::time_point& last_flush)
|
inline void spdlog::details::async_log_helper::handle_flush_interval(log_clock::time_point& now, log_clock::time_point& last_flush)
|
||||||
{
|
{
|
||||||
auto should_flush = _flush_requested || (_flush_interval_ms != std::chrono::milliseconds::zero() && now - last_flush >= _flush_interval_ms);
|
auto should_flush = _flush_requested || (_flush_interval_ms != std::chrono::milliseconds::zero() && now - last_flush >= _flush_interval_ms);
|
||||||
if (should_flush) {
|
if (should_flush)
|
||||||
|
{
|
||||||
for (auto &s : _sinks)
|
for (auto &s : _sinks)
|
||||||
s->flush();
|
s->flush();
|
||||||
now = last_flush = details::os::now();
|
now = last_flush = details::os::now();
|
||||||
@ -362,7 +376,8 @@ inline void spdlog::details::async_log_helper::sleep_or_yield(const spdlog::log_
|
|||||||
inline void spdlog::details::async_log_helper::wait_empty_q()
|
inline void spdlog::details::async_log_helper::wait_empty_q()
|
||||||
{
|
{
|
||||||
auto last_op = details::os::now();
|
auto last_op = details::os::now();
|
||||||
while (_q.approx_size() > 0) {
|
while (_q.approx_size() > 0)
|
||||||
|
{
|
||||||
sleep_or_yield(details::os::now(), last_op);
|
sleep_or_yield(details::os::now(), last_op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -13,12 +13,15 @@
|
|||||||
#include "format.h"
|
#include "format.h"
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
namespace fmt {
|
namespace fmt
|
||||||
|
{
|
||||||
|
|
||||||
namespace internal {
|
namespace internal
|
||||||
|
{
|
||||||
|
|
||||||
template <class Char>
|
template <class Char>
|
||||||
class FormatBuf : public std::basic_streambuf<Char> {
|
class FormatBuf : public std::basic_streambuf<Char>
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
typedef typename std::basic_streambuf<Char>::int_type int_type;
|
typedef typename std::basic_streambuf<Char>::int_type int_type;
|
||||||
typedef typename std::basic_streambuf<Char>::traits_type traits_type;
|
typedef typename std::basic_streambuf<Char>::traits_type traits_type;
|
||||||
@ -27,12 +30,15 @@ class FormatBuf : public std::basic_streambuf<Char> {
|
|||||||
Char *start_;
|
Char *start_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0]) {
|
FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0])
|
||||||
|
{
|
||||||
this->setp(start_, start_ + buffer_.capacity());
|
this->setp(start_, start_ + buffer_.capacity());
|
||||||
}
|
}
|
||||||
|
|
||||||
int_type overflow(int_type ch = traits_type::eof()) {
|
int_type overflow(int_type ch = traits_type::eof())
|
||||||
if (!traits_type::eq_int_type(ch, traits_type::eof())) {
|
{
|
||||||
|
if (!traits_type::eq_int_type(ch, traits_type::eof()))
|
||||||
|
{
|
||||||
size_t buf_size = size();
|
size_t buf_size = size();
|
||||||
buffer_.resize(buf_size);
|
buffer_.resize(buf_size);
|
||||||
buffer_.reserve(buf_size * 2);
|
buffer_.reserve(buf_size * 2);
|
||||||
@ -44,14 +50,16 @@ class FormatBuf : public std::basic_streambuf<Char> {
|
|||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const
|
||||||
|
{
|
||||||
return to_unsigned(this->pptr() - start_);
|
return to_unsigned(this->pptr() - start_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Yes &convert(std::ostream &);
|
Yes &convert(std::ostream &);
|
||||||
|
|
||||||
struct DummyStream : std::ostream {
|
struct DummyStream : std::ostream
|
||||||
|
{
|
||||||
DummyStream(); // Suppress a bogus warning in MSVC.
|
DummyStream(); // Suppress a bogus warning in MSVC.
|
||||||
// Hide all operator<< overloads from std::ostream.
|
// Hide all operator<< overloads from std::ostream.
|
||||||
void operator<<(Null<>);
|
void operator<<(Null<>);
|
||||||
@ -60,9 +68,11 @@ struct DummyStream : std::ostream {
|
|||||||
No &operator<<(std::ostream &, int);
|
No &operator<<(std::ostream &, int);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct ConvertToIntImpl<T, true> {
|
struct ConvertToIntImpl<T, true>
|
||||||
|
{
|
||||||
// Convert to int only if T doesn't have an overloaded operator<<.
|
// Convert to int only if T doesn't have an overloaded operator<<.
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No)
|
value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -71,7 +81,8 @@ struct ConvertToIntImpl<T, true> {
|
|||||||
// Formats a value.
|
// Formats a value.
|
||||||
template <typename Char, typename ArgFormatter, typename T>
|
template <typename Char, typename ArgFormatter, typename T>
|
||||||
void format(BasicFormatter<Char, ArgFormatter> &f,
|
void format(BasicFormatter<Char, ArgFormatter> &f,
|
||||||
const Char *&format_str, const T &value) {
|
const Char *&format_str, const T &value)
|
||||||
|
{
|
||||||
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
|
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
|
||||||
|
|
||||||
internal::FormatBuf<Char> format_buf(buffer);
|
internal::FormatBuf<Char> format_buf(buffer);
|
||||||
|
@ -83,21 +83,28 @@
|
|||||||
|
|
||||||
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
|
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
|
||||||
|
|
||||||
namespace fmt {
|
namespace fmt
|
||||||
|
{
|
||||||
|
|
||||||
// An error code.
|
// An error code.
|
||||||
class ErrorCode {
|
class ErrorCode
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
int value_;
|
int value_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ErrorCode(int value = 0) FMT_NOEXCEPT : value_(value) {}
|
explicit ErrorCode(int value = 0) FMT_NOEXCEPT :
|
||||||
|
value_(value) {}
|
||||||
|
|
||||||
int get() const FMT_NOEXCEPT { return value_; }
|
int get() const FMT_NOEXCEPT
|
||||||
|
{
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A buffered file.
|
// A buffered file.
|
||||||
class BufferedFile {
|
class BufferedFile
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
FILE *file_;
|
FILE *file_;
|
||||||
|
|
||||||
@ -107,7 +114,8 @@ class BufferedFile {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructs a BufferedFile object which doesn't represent any file.
|
// Constructs a BufferedFile object which doesn't represent any file.
|
||||||
BufferedFile() FMT_NOEXCEPT : file_(0) {}
|
BufferedFile() FMT_NOEXCEPT :
|
||||||
|
file_(0) {}
|
||||||
|
|
||||||
// Destroys the object closing the file it represents if any.
|
// Destroys the object closing the file it represents if any.
|
||||||
~BufferedFile() FMT_NOEXCEPT;
|
~BufferedFile() FMT_NOEXCEPT;
|
||||||
@ -119,28 +127,34 @@ class BufferedFile {
|
|||||||
private:
|
private:
|
||||||
// A proxy object to emulate a move constructor.
|
// A proxy object to emulate a move constructor.
|
||||||
// It is private to make it impossible call operator Proxy directly.
|
// It is private to make it impossible call operator Proxy directly.
|
||||||
struct Proxy {
|
struct Proxy
|
||||||
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// A "move constructor" for moving from a temporary.
|
// A "move constructor" for moving from a temporary.
|
||||||
BufferedFile(Proxy p) FMT_NOEXCEPT : file_(p.file) {}
|
BufferedFile(Proxy p) FMT_NOEXCEPT :
|
||||||
|
file_(p.file) {}
|
||||||
|
|
||||||
// A "move constructor" for moving from an lvalue.
|
// A "move constructor" for moving from an lvalue.
|
||||||
BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_) {
|
BufferedFile(BufferedFile &f) FMT_NOEXCEPT :
|
||||||
|
file_(f.file_)
|
||||||
|
{
|
||||||
f.file_ = 0;
|
f.file_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A "move assignment operator" for moving from a temporary.
|
// A "move assignment operator" for moving from a temporary.
|
||||||
BufferedFile &operator=(Proxy p) {
|
BufferedFile &operator=(Proxy p)
|
||||||
|
{
|
||||||
close();
|
close();
|
||||||
file_ = p.file;
|
file_ = p.file;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A "move assignment operator" for moving from an lvalue.
|
// A "move assignment operator" for moving from an lvalue.
|
||||||
BufferedFile &operator=(BufferedFile &other) {
|
BufferedFile &operator=(BufferedFile &other)
|
||||||
|
{
|
||||||
close();
|
close();
|
||||||
file_ = other.file_;
|
file_ = other.file_;
|
||||||
other.file_ = 0;
|
other.file_ = 0;
|
||||||
@ -149,7 +163,8 @@ public:
|
|||||||
|
|
||||||
// Returns a proxy object for moving from a temporary:
|
// Returns a proxy object for moving from a temporary:
|
||||||
// BufferedFile file = BufferedFile(...);
|
// BufferedFile file = BufferedFile(...);
|
||||||
operator Proxy() FMT_NOEXCEPT {
|
operator Proxy() FMT_NOEXCEPT
|
||||||
|
{
|
||||||
Proxy p = {file_};
|
Proxy p = {file_};
|
||||||
file_ = 0;
|
file_ = 0;
|
||||||
return p;
|
return p;
|
||||||
@ -160,11 +175,14 @@ public:
|
|||||||
FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile);
|
FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_) {
|
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT :
|
||||||
|
file_(other.file_)
|
||||||
|
{
|
||||||
other.file_ = 0;
|
other.file_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedFile& operator=(BufferedFile &&other) {
|
BufferedFile& operator=(BufferedFile &&other)
|
||||||
|
{
|
||||||
close();
|
close();
|
||||||
file_ = other.file_;
|
file_ = other.file_;
|
||||||
other.file_ = 0;
|
other.file_ = 0;
|
||||||
@ -179,13 +197,17 @@ public:
|
|||||||
void close();
|
void close();
|
||||||
|
|
||||||
// Returns the pointer to a FILE object representing this file.
|
// Returns the pointer to a FILE object representing this file.
|
||||||
FILE *get() const FMT_NOEXCEPT { return file_; }
|
FILE *get() const FMT_NOEXCEPT
|
||||||
|
{
|
||||||
|
return file_;
|
||||||
|
}
|
||||||
|
|
||||||
// We place parentheses around fileno to workaround a bug in some versions
|
// We place parentheses around fileno to workaround a bug in some versions
|
||||||
// of MinGW that define fileno as a macro.
|
// of MinGW that define fileno as a macro.
|
||||||
int (fileno)() const;
|
int (fileno)() const;
|
||||||
|
|
||||||
void print(CStringRef format_str, const ArgList &args) {
|
void print(CStringRef format_str, const ArgList &args)
|
||||||
|
{
|
||||||
fmt::print(file_, format_str, args);
|
fmt::print(file_, format_str, args);
|
||||||
}
|
}
|
||||||
FMT_VARIADIC(void, print, CStringRef)
|
FMT_VARIADIC(void, print, CStringRef)
|
||||||
@ -197,7 +219,8 @@ public:
|
|||||||
// closing the file multiple times will cause a crash on Windows rather
|
// closing the file multiple times will cause a crash on Windows rather
|
||||||
// than an exception. You can get standard behavior by overriding the
|
// than an exception. You can get standard behavior by overriding the
|
||||||
// invalid parameter handler with _set_invalid_parameter_handler.
|
// invalid parameter handler with _set_invalid_parameter_handler.
|
||||||
class File {
|
class File
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
int fd_; // File descriptor.
|
int fd_; // File descriptor.
|
||||||
|
|
||||||
@ -206,14 +229,16 @@ class File {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Possible values for the oflag argument to the constructor.
|
// Possible values for the oflag argument to the constructor.
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
|
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
|
||||||
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
|
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
|
||||||
RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing.
|
RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Constructs a File object which doesn't represent any file.
|
// Constructs a File object which doesn't represent any file.
|
||||||
File() FMT_NOEXCEPT : fd_(-1) {}
|
File() FMT_NOEXCEPT :
|
||||||
|
fd_(-1) {}
|
||||||
|
|
||||||
// Opens a file and constructs a File object representing this file.
|
// Opens a file and constructs a File object representing this file.
|
||||||
File(CStringRef path, int oflag);
|
File(CStringRef path, int oflag);
|
||||||
@ -225,28 +250,34 @@ class File {
|
|||||||
private:
|
private:
|
||||||
// A proxy object to emulate a move constructor.
|
// A proxy object to emulate a move constructor.
|
||||||
// It is private to make it impossible call operator Proxy directly.
|
// It is private to make it impossible call operator Proxy directly.
|
||||||
struct Proxy {
|
struct Proxy
|
||||||
|
{
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// A "move constructor" for moving from a temporary.
|
// A "move constructor" for moving from a temporary.
|
||||||
File(Proxy p) FMT_NOEXCEPT : fd_(p.fd) {}
|
File(Proxy p) FMT_NOEXCEPT :
|
||||||
|
fd_(p.fd) {}
|
||||||
|
|
||||||
// A "move constructor" for moving from an lvalue.
|
// A "move constructor" for moving from an lvalue.
|
||||||
File(File &other) FMT_NOEXCEPT : fd_(other.fd_) {
|
File(File &other) FMT_NOEXCEPT :
|
||||||
|
fd_(other.fd_)
|
||||||
|
{
|
||||||
other.fd_ = -1;
|
other.fd_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A "move assignment operator" for moving from a temporary.
|
// A "move assignment operator" for moving from a temporary.
|
||||||
File &operator=(Proxy p) {
|
File &operator=(Proxy p)
|
||||||
|
{
|
||||||
close();
|
close();
|
||||||
fd_ = p.fd;
|
fd_ = p.fd;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A "move assignment operator" for moving from an lvalue.
|
// A "move assignment operator" for moving from an lvalue.
|
||||||
File &operator=(File &other) {
|
File &operator=(File &other)
|
||||||
|
{
|
||||||
close();
|
close();
|
||||||
fd_ = other.fd_;
|
fd_ = other.fd_;
|
||||||
other.fd_ = -1;
|
other.fd_ = -1;
|
||||||
@ -255,7 +286,8 @@ class File {
|
|||||||
|
|
||||||
// Returns a proxy object for moving from a temporary:
|
// Returns a proxy object for moving from a temporary:
|
||||||
// File file = File(...);
|
// File file = File(...);
|
||||||
operator Proxy() FMT_NOEXCEPT {
|
operator Proxy() FMT_NOEXCEPT
|
||||||
|
{
|
||||||
Proxy p = {fd_};
|
Proxy p = {fd_};
|
||||||
fd_ = -1;
|
fd_ = -1;
|
||||||
return p;
|
return p;
|
||||||
@ -266,11 +298,14 @@ class File {
|
|||||||
FMT_DISALLOW_COPY_AND_ASSIGN(File);
|
FMT_DISALLOW_COPY_AND_ASSIGN(File);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
File(File &&other) FMT_NOEXCEPT : fd_(other.fd_) {
|
File(File &&other) FMT_NOEXCEPT :
|
||||||
|
fd_(other.fd_)
|
||||||
|
{
|
||||||
other.fd_ = -1;
|
other.fd_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
File& operator=(File &&other) {
|
File& operator=(File &&other)
|
||||||
|
{
|
||||||
close();
|
close();
|
||||||
fd_ = other.fd_;
|
fd_ = other.fd_;
|
||||||
other.fd_ = -1;
|
other.fd_ = -1;
|
||||||
@ -282,7 +317,10 @@ class File {
|
|||||||
~File() FMT_NOEXCEPT;
|
~File() FMT_NOEXCEPT;
|
||||||
|
|
||||||
// Returns the file descriptor.
|
// Returns the file descriptor.
|
||||||
int descriptor() const FMT_NOEXCEPT { return fd_; }
|
int descriptor() const FMT_NOEXCEPT
|
||||||
|
{
|
||||||
|
return fd_;
|
||||||
|
}
|
||||||
|
|
||||||
// Closes the file.
|
// Closes the file.
|
||||||
void close();
|
void close();
|
||||||
@ -328,22 +366,26 @@ long getpagesize();
|
|||||||
|
|
||||||
#ifdef FMT_LOCALE
|
#ifdef FMT_LOCALE
|
||||||
// A "C" numeric locale.
|
// A "C" numeric locale.
|
||||||
class Locale {
|
class Locale
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
# ifdef _MSC_VER
|
# ifdef _MSC_VER
|
||||||
typedef _locale_t locale_t;
|
typedef _locale_t locale_t;
|
||||||
|
|
||||||
enum { LC_NUMERIC_MASK = LC_NUMERIC };
|
enum { LC_NUMERIC_MASK = LC_NUMERIC };
|
||||||
|
|
||||||
static locale_t newlocale(int category_mask, const char *locale, locale_t) {
|
static locale_t newlocale(int category_mask, const char *locale, locale_t)
|
||||||
|
{
|
||||||
return _create_locale(category_mask, locale);
|
return _create_locale(category_mask, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freelocale(locale_t locale) {
|
static void freelocale(locale_t locale)
|
||||||
|
{
|
||||||
_free_locale(locale);
|
_free_locale(locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double strtod_l(const char *nptr, char **endptr, _locale_t locale) {
|
static double strtod_l(const char *nptr, char **endptr, _locale_t locale)
|
||||||
|
{
|
||||||
return _strtod_l(nptr, endptr, locale);
|
return _strtod_l(nptr, endptr, locale);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
@ -355,17 +397,25 @@ class Locale {
|
|||||||
public:
|
public:
|
||||||
typedef locale_t Type;
|
typedef locale_t Type;
|
||||||
|
|
||||||
Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", NULL)) {
|
Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", NULL))
|
||||||
|
{
|
||||||
if (!locale_)
|
if (!locale_)
|
||||||
FMT_THROW(fmt::SystemError(errno, "cannot create locale"));
|
FMT_THROW(fmt::SystemError(errno, "cannot create locale"));
|
||||||
}
|
}
|
||||||
~Locale() { freelocale(locale_); }
|
~Locale()
|
||||||
|
{
|
||||||
|
freelocale(locale_);
|
||||||
|
}
|
||||||
|
|
||||||
Type get() const { return locale_; }
|
Type get() const
|
||||||
|
{
|
||||||
|
return locale_;
|
||||||
|
}
|
||||||
|
|
||||||
// Converts string to floating-point number and advances str past the end
|
// Converts string to floating-point number and advances str past the end
|
||||||
// of the parsed input.
|
// of the parsed input.
|
||||||
double strtod(const char *&str) const {
|
double strtod(const char *&str) const
|
||||||
|
{
|
||||||
char *end = 0;
|
char *end = 0;
|
||||||
double result = strtod_l(str, &end, locale_);
|
double result = strtod_l(str, &end, locale_);
|
||||||
str = end;
|
str = end;
|
||||||
@ -376,10 +426,17 @@ class Locale {
|
|||||||
} // namespace fmt
|
} // namespace fmt
|
||||||
|
|
||||||
#if !FMT_USE_RVALUE_REFERENCES
|
#if !FMT_USE_RVALUE_REFERENCES
|
||||||
namespace std {
|
namespace std
|
||||||
|
{
|
||||||
// For compatibility with C++98.
|
// For compatibility with C++98.
|
||||||
inline fmt::BufferedFile &move(fmt::BufferedFile &f) { return f; }
|
inline fmt::BufferedFile &move(fmt::BufferedFile &f)
|
||||||
inline fmt::File &move(fmt::File &f) { return f; }
|
{
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
inline fmt::File &move(fmt::File &f)
|
||||||
|
{
|
||||||
|
return f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -13,10 +13,12 @@
|
|||||||
#include "format.h"
|
#include "format.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
namespace fmt {
|
namespace fmt
|
||||||
|
{
|
||||||
template <typename ArgFormatter>
|
template <typename ArgFormatter>
|
||||||
void format(BasicFormatter<char, ArgFormatter> &f,
|
void format(BasicFormatter<char, ArgFormatter> &f,
|
||||||
const char *&format_str, const std::tm &tm) {
|
const char *&format_str, const std::tm &tm)
|
||||||
|
{
|
||||||
if (*format_str == ':')
|
if (*format_str == ':')
|
||||||
++format_str;
|
++format_str;
|
||||||
const char *end = format_str;
|
const char *end = format_str;
|
||||||
@ -29,14 +31,17 @@ void format(BasicFormatter<char, ArgFormatter> &f,
|
|||||||
format[format.size() - 1] = '\0';
|
format[format.size() - 1] = '\0';
|
||||||
Buffer<char> &buffer = f.writer().buffer();
|
Buffer<char> &buffer = f.writer().buffer();
|
||||||
std::size_t start = buffer.size();
|
std::size_t start = buffer.size();
|
||||||
for (;;) {
|
for (;;)
|
||||||
|
{
|
||||||
std::size_t size = buffer.capacity() - start;
|
std::size_t size = buffer.capacity() - start;
|
||||||
std::size_t count = std::strftime(&buffer[start], size, &format[0], &tm);
|
std::size_t count = std::strftime(&buffer[start], size, &format[0], &tm);
|
||||||
if (count != 0) {
|
if (count != 0)
|
||||||
|
{
|
||||||
buffer.resize(start + count);
|
buffer.resize(start + count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (size >= format.size() * 256) {
|
if (size >= format.size() * 256)
|
||||||
|
{
|
||||||
// If the buffer is 256 times larger than the format string, assume
|
// If the buffer is 256 times larger than the format string, assume
|
||||||
// that `strftime` gives an empty result. There doesn't seem to be a
|
// that `strftime` gives an empty result. There doesn't seem to be a
|
||||||
// better way to distinguish the two cases:
|
// better way to distinguish the two cases:
|
||||||
|
@ -45,7 +45,8 @@ TEST_CASE("custom_error_handler", "[errors]]")
|
|||||||
std::string filename = "logs/simple_log.txt";
|
std::string filename = "logs/simple_log.txt";
|
||||||
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
|
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
|
||||||
logger->flush_on(spdlog::level::info);
|
logger->flush_on(spdlog::level::info);
|
||||||
logger->set_error_handler([=](const std::string& msg) {
|
logger->set_error_handler([=](const std::string& msg)
|
||||||
|
{
|
||||||
throw custom_ex();
|
throw custom_ex();
|
||||||
});
|
});
|
||||||
logger->info("Good message #1");
|
logger->info("Good message #1");
|
||||||
@ -58,7 +59,8 @@ TEST_CASE("default_error_handler2", "[errors]]")
|
|||||||
{
|
{
|
||||||
|
|
||||||
auto logger = spdlog::create<failing_sink>("failed_logger");
|
auto logger = spdlog::create<failing_sink>("failed_logger");
|
||||||
logger->set_error_handler([=](const std::string& msg) {
|
logger->set_error_handler([=](const std::string& msg)
|
||||||
|
{
|
||||||
throw custom_ex();
|
throw custom_ex();
|
||||||
});
|
});
|
||||||
REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
|
REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
|
||||||
@ -72,7 +74,8 @@ TEST_CASE("async_error_handler", "[errors]]")
|
|||||||
std::string filename = "logs/simple_async_log.txt";
|
std::string filename = "logs/simple_async_log.txt";
|
||||||
{
|
{
|
||||||
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
|
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename, true);
|
||||||
logger->set_error_handler([=](const std::string& msg) {
|
logger->set_error_handler([=](const std::string& msg)
|
||||||
|
{
|
||||||
std::ofstream ofs("logs/custom_err.txt");
|
std::ofstream ofs("logs/custom_err.txt");
|
||||||
if (!ofs) throw std::runtime_error("Failed open logs/custom_err.txt");
|
if (!ofs) throw std::runtime_error("Failed open logs/custom_err.txt");
|
||||||
ofs << err_msg;
|
ofs << err_msg;
|
||||||
@ -95,7 +98,8 @@ TEST_CASE("async_error_handler2", "[errors]]")
|
|||||||
spdlog::set_async_mode(128);
|
spdlog::set_async_mode(128);
|
||||||
{
|
{
|
||||||
auto logger = spdlog::create<failing_sink>("failed_logger");
|
auto logger = spdlog::create<failing_sink>("failed_logger");
|
||||||
logger->set_error_handler([=](const std::string& msg) {
|
logger->set_error_handler([=](const std::string& msg)
|
||||||
|
{
|
||||||
std::ofstream ofs("logs/custom_err2.txt");
|
std::ofstream ofs("logs/custom_err2.txt");
|
||||||
if (!ofs) throw std::runtime_error("Failed open logs/custom_err2.txt");
|
if (!ofs) throw std::runtime_error("Failed open logs/custom_err2.txt");
|
||||||
ofs << err_msg;
|
ofs << err_msg;
|
||||||
|
Loading…
Reference in New Issue
Block a user