Commit 5653e5c9 authored by gabime's avatar gabime

astyle

parent 6312748c
...@@ -253,7 +253,7 @@ inline void spdlog::details::async_log_helper::push_msg(details::async_log_helpe ...@@ -253,7 +253,7 @@ inline void spdlog::details::async_log_helper::push_msg(details::async_log_helpe
inline void spdlog::details::async_log_helper::flush(bool wait_for_q) inline void spdlog::details::async_log_helper::flush(bool wait_for_q)
{ {
push_msg(async_msg(async_msg_type::flush)); push_msg(async_msg(async_msg_type::flush));
if(wait_for_q) if(wait_for_q)
wait_empty_q(); //return only make after the above flush message was processed wait_empty_q(); //return only make after the above flush message was processed
} }
...@@ -303,8 +303,10 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_ ...@@ -303,8 +303,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);
} }
} }
......
...@@ -245,8 +245,10 @@ inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) cons ...@@ -245,8 +245,10 @@ inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) cons
inline void spdlog::logger::_sink_it(details::log_msg& msg) inline void spdlog::logger::_sink_it(details::log_msg& msg)
{ {
_formatter->format(msg); _formatter->format(msg);
for (auto &sink : _sinks){ for (auto &sink : _sinks)
if( sink->should_log( msg.level)){ {
if( sink->should_log( msg.level))
{
sink->log(msg); sink->log(msg);
} }
} }
......
...@@ -108,7 +108,7 @@ inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string& ...@@ -108,7 +108,7 @@ inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string&
#if defined(__ANDROID__) #if defined(__ANDROID__)
inline std::shared_ptr<spdlog::logger> spdlog::android_logger(const std::string& logger_name, const std::string& tag) inline std::shared_ptr<spdlog::logger> spdlog::android_logger(const std::string& logger_name, const std::string& tag)
{ {
return create<spdlog::sinks::android_sink>(logger_name, tag); return create<spdlog::sinks::android_sink>(logger_name, tag);
} }
#endif #endif
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -14,58 +14,68 @@ ...@@ -14,58 +14,68 @@
// #include "fmt/format.h" // #include "fmt/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: {
typedef typename std::basic_streambuf<Char>::int_type int_type; private:
typedef typename std::basic_streambuf<Char>::traits_type traits_type; typedef typename std::basic_streambuf<Char>::int_type int_type;
typedef typename std::basic_streambuf<Char>::traits_type traits_type;
Buffer<Char> &buffer_;
Char *start_; Buffer<Char> &buffer_;
Char *start_;
public:
FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0]) { public:
this->setp(start_, start_ + buffer_.capacity()); FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0])
} {
this->setp(start_, start_ + buffer_.capacity());
int_type overflow(int_type ch = traits_type::eof()) {
if (!traits_type::eq_int_type(ch, traits_type::eof())) {
size_t buf_size = size();
buffer_.resize(buf_size);
buffer_.reserve(buf_size * 2);
start_ = &buffer_[0];
start_[buf_size] = traits_type::to_char_type(ch);
this->setp(start_+ buf_size + 1, start_ + buf_size * 2);
} }
return ch;
}
size_t size() const { int_type overflow(int_type ch = traits_type::eof())
return to_unsigned(this->pptr() - start_); {
} if (!traits_type::eq_int_type(ch, traits_type::eof()))
{
size_t buf_size = size();
buffer_.resize(buf_size);
buffer_.reserve(buf_size * 2);
start_ = &buffer_[0];
start_[buf_size] = traits_type::to_char_type(ch);
this->setp(start_+ buf_size + 1, start_ + buf_size * 2);
}
return ch;
}
size_t size() const
{
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. {
// Hide all operator<< overloads from std::ostream. DummyStream(); // Suppress a bogus warning in MSVC.
void operator<<(Null<>); // Hide all operator<< overloads from std::ostream.
void operator<<(Null<>);
}; };
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<<. {
enum { // Convert to int only if T doesn't have an overloaded operator<<.
value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No) enum
}; {
value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No)
};
}; };
// Write the content of w to os. // Write the content of w to os.
...@@ -75,16 +85,17 @@ void write(std::ostream &os, Writer &w); ...@@ -75,16 +85,17 @@ void write(std::ostream &os, Writer &w);
// Formats a value. // Formats a value.
template <typename Char, typename ArgFormatter, typename T> template <typename Char, typename ArgFormatter, typename T>
void format_arg(BasicFormatter<Char, ArgFormatter> &f, void format_arg(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);
std::basic_ostream<Char> output(&format_buf); std::basic_ostream<Char> output(&format_buf);
output << value; output << value;
BasicStringRef<Char> str(&buffer[0], format_buf.size()); BasicStringRef<Char> str(&buffer[0], format_buf.size());
typedef internal::MakeArg< BasicFormatter<Char> > MakeArg; typedef internal::MakeArg< BasicFormatter<Char> > MakeArg;
format_str = f.format(format_str, MakeArg(str)); format_str = f.format(format_str, MakeArg(str));
} }
/** /**
......
...@@ -15,60 +15,81 @@ ...@@ -15,60 +15,81 @@
#include "fmt/ostream.h" #include "fmt/ostream.h"
namespace fmt { namespace fmt
namespace internal { {
namespace internal
{
// Checks if a value fits in int - used to avoid warnings about comparing // Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers. // signed and unsigned integers.
template <bool IsSigned> template <bool IsSigned>
struct IntChecker { struct IntChecker
template <typename T> {
static bool fits_in_int(T value) { template <typename T>
unsigned max = std::numeric_limits<int>::max(); static bool fits_in_int(T value)
return value <= max; {
} unsigned max = std::numeric_limits<int>::max();
static bool fits_in_int(bool) { return true; } return value <= max;
}
static bool fits_in_int(bool)
{
return true;
}
}; };
template <> template <>
struct IntChecker<true> { struct IntChecker<true>
template <typename T> {
static bool fits_in_int(T value) { template <typename T>
return value >= std::numeric_limits<int>::min() && static bool fits_in_int(T value)
value <= std::numeric_limits<int>::max(); {
} return value >= std::numeric_limits<int>::min() &&
static bool fits_in_int(int) { return true; } value <= std::numeric_limits<int>::max();
}
static bool fits_in_int(int)
{
return true;
}
}; };
class PrecisionHandler : public ArgVisitor<PrecisionHandler, int> { class PrecisionHandler : public ArgVisitor<PrecisionHandler, int>
public: {
void report_unhandled_arg() { public:
FMT_THROW(FormatError("precision is not integer")); void report_unhandled_arg()
} {
FMT_THROW(FormatError("precision is not integer"));
template <typename T> }
int visit_any_int(T value) {
if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value)) template <typename T>
FMT_THROW(FormatError("number is too big")); int visit_any_int(T value)
return static_cast<int>(value); {
} if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
FMT_THROW(FormatError("number is too big"));
return static_cast<int>(value);
}
}; };
// IsZeroInt::visit(arg) returns true iff arg is a zero integer. // IsZeroInt::visit(arg) returns true iff arg is a zero integer.
class IsZeroInt : public ArgVisitor<IsZeroInt, bool> { class IsZeroInt : public ArgVisitor<IsZeroInt, bool>
public: {
template <typename T> public:
bool visit_any_int(T value) { return value == 0; } template <typename T>
bool visit_any_int(T value)
{
return value == 0;
}
}; };
template <typename T, typename U> template <typename T, typename U>
struct is_same { struct is_same
enum { value = 0 }; {
enum { value = 0 };
}; };
template <typename T> template <typename T>
struct is_same<T, T> { struct is_same<T, T>
enum { value = 1 }; {
enum { value = 1 };
}; };
// An argument visitor that converts an integer argument to T for printf, // An argument visitor that converts an integer argument to T for printf,
...@@ -76,99 +97,117 @@ struct is_same<T, T> { ...@@ -76,99 +97,117 @@ struct is_same<T, T> {
// corresponding signed or unsigned type depending on the type specifier: // corresponding signed or unsigned type depending on the type specifier:
// 'd' and 'i' - signed, other - unsigned) // 'd' and 'i' - signed, other - unsigned)
template <typename T = void> template <typename T = void>
class ArgConverter : public ArgVisitor<ArgConverter<T>, void> { class ArgConverter : public ArgVisitor<ArgConverter<T>, void>
private: {
internal::Arg &arg_; private:
wchar_t type_; internal::Arg &arg_;
wchar_t type_;
FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
public:
ArgConverter(internal::Arg &arg, wchar_t type) public:
: arg_(arg), type_(type) {} ArgConverter(internal::Arg &arg, wchar_t type)
: arg_(arg), type_(type) {}
void visit_bool(bool value) {
if (type_ != 's') void visit_bool(bool value)
visit_any_int(value); {
} if (type_ != 's')
visit_any_int(value);
template <typename U> }
void visit_any_int(U value) {
bool is_signed = type_ == 'd' || type_ == 'i'; template <typename U>
using internal::Arg; void visit_any_int(U value)
typedef typename internal::Conditional< {
bool is_signed = type_ == 'd' || type_ == 'i';
using internal::Arg;
typedef typename internal::Conditional<
is_same<T, void>::value, U, T>::type TargetType; is_same<T, void>::value, U, T>::type TargetType;
if (sizeof(TargetType) <= sizeof(int)) { if (sizeof(TargetType) <= sizeof(int))
// Extra casts are used to silence warnings. {
if (is_signed) { // Extra casts are used to silence warnings.
arg_.type = Arg::INT; if (is_signed)
arg_.int_value = static_cast<int>(static_cast<TargetType>(value)); {
} else { arg_.type = Arg::INT;
arg_.type = Arg::UINT; arg_.int_value = static_cast<int>(static_cast<TargetType>(value));
typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned; }
arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value)); else
} {
} else { arg_.type = Arg::UINT;
if (is_signed) { typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned;
arg_.type = Arg::LONG_LONG; arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value));
// glibc's printf doesn't sign extend arguments of smaller types: }
// std::printf("%lld", -42); // prints "4294967254" }
// but we don't have to do the same because it's a UB. else
arg_.long_long_value = static_cast<LongLong>(value); {
} else { if (is_signed)
arg_.type = Arg::ULONG_LONG; {
arg_.ulong_long_value = arg_.type = Arg::LONG_LONG;
static_cast<typename internal::MakeUnsigned<U>::Type>(value); // glibc's printf doesn't sign extend arguments of smaller types:
} // std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
arg_.long_long_value = static_cast<LongLong>(value);
}
else
{
arg_.type = Arg::ULONG_LONG;
arg_.ulong_long_value =
static_cast<typename internal::MakeUnsigned<U>::Type>(value);
}
}
} }
}
}; };
// Converts an integer argument to char for printf. // Converts an integer argument to char for printf.
class CharConverter : public ArgVisitor<CharConverter, void> { class CharConverter : public ArgVisitor<CharConverter, void>
private: {
internal::Arg &arg_; private:
internal::Arg &arg_;
FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter); FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);
public: public:
explicit CharConverter(internal::Arg &arg) : arg_(arg) {} explicit CharConverter(internal::Arg &arg) : arg_(arg) {}
template <typename T> template <typename T>
void visit_any_int(T value) { void visit_any_int(T value)
arg_.type = internal::Arg::CHAR; {
arg_.int_value = static_cast<char>(value); arg_.type = internal::Arg::CHAR;
} arg_.int_value = static_cast<char>(value);
}
}; };
// Checks if an argument is a valid printf width specifier and sets // Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative. // left alignment if it is negative.
class WidthHandler : public ArgVisitor<WidthHandler, unsigned> { class WidthHandler : public ArgVisitor<WidthHandler, unsigned>
private: {
FormatSpec &spec_; private:
FormatSpec &spec_;
FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
public:
explicit WidthHandler(FormatSpec &spec) : spec_(spec) {} public:
explicit WidthHandler(FormatSpec &spec) : spec_(spec) {}
void report_unhandled_arg() {
FMT_THROW(FormatError("width is not integer")); void report_unhandled_arg()
} {
FMT_THROW(FormatError("width is not integer"));
template <typename T> }
unsigned visit_any_int(T value) {
typedef typename internal::IntTraits<T>::MainType UnsignedType; template <typename T>
UnsignedType width = static_cast<UnsignedType>(value); unsigned visit_any_int(T value)
if (internal::is_negative(value)) { {
spec_.align_ = ALIGN_LEFT; typedef typename internal::IntTraits<T>::MainType UnsignedType;
width = 0 - width; UnsignedType width = static_cast<UnsignedType>(value);
if (internal::is_negative(value))
{
spec_.align_ = ALIGN_LEFT;
width = 0 - width;
}
unsigned int_max = std::numeric_limits<int>::max();
if (width > int_max)
FMT_THROW(FormatError("number is too big"));
return static_cast<unsigned>(width);
} }
unsigned int_max = std::numeric_limits<int>::max();
if (width > int_max)
FMT_THROW(FormatError("number is too big"));
return static_cast<unsigned>(width);
}
}; };
} // namespace internal } // namespace internal
...@@ -190,302 +229,343 @@ class WidthHandler : public ArgVisitor<WidthHandler, unsigned> { ...@@ -190,302 +229,343 @@ class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
\endrst \endrst
*/ */
template <typename Impl, typename Char> template <typename Impl, typename Char>
class BasicPrintfArgFormatter : public internal::ArgFormatterBase<Impl, Char> { class BasicPrintfArgFormatter : public internal::ArgFormatterBase<Impl, Char>
private: {
void write_null_pointer() { private:
this->spec().type_ = 0; void write_null_pointer()
this->write("(nil)"); {
} this->spec().type_ = 0;
this->write("(nil)");
typedef internal::ArgFormatterBase<Impl, Char> Base; }
public: typedef internal::ArgFormatterBase<Impl, Char> Base;
/**
\rst public:
Constructs an argument formatter object. /**
*writer* is a reference to the output writer and *spec* contains format \rst
specifier information for standard argument types. Constructs an argument formatter object.
\endrst *writer* is a reference to the output writer and *spec* contains format
*/ specifier information for standard argument types.
BasicPrintfArgFormatter(BasicWriter<Char> &writer, FormatSpec &spec) \endrst
: internal::ArgFormatterBase<Impl, Char>(writer, spec) {} */
BasicPrintfArgFormatter(BasicWriter<Char> &writer, FormatSpec &spec)
/** Formats an argument of type ``bool``. */ : internal::ArgFormatterBase<Impl, Char>(writer, spec) {}
void visit_bool(bool value) {
FormatSpec &fmt_spec = this->spec(); /** Formats an argument of type ``bool``. */
if (fmt_spec.type_ != 's') void visit_bool(bool value)
return this->visit_any_int(value); {
fmt_spec.type_ = 0; FormatSpec &fmt_spec = this->spec();
this->write(value); if (fmt_spec.type_ != 's')
} return this->visit_any_int(value);
fmt_spec.type_ = 0;
/** Formats a character. */ this->write(value);
void visit_char(int value) { }
const FormatSpec &fmt_spec = this->spec();
BasicWriter<Char> &w = this->writer(); /** Formats a character. */
if (fmt_spec.type_ && fmt_spec.type_ != 'c') void visit_char(int value)
w.write_int(value, fmt_spec); {
typedef typename BasicWriter<Char>::CharPtr CharPtr; const FormatSpec &fmt_spec = this->spec();
CharPtr out = CharPtr(); BasicWriter<Char> &w = this->writer();
if (fmt_spec.width_ > 1) { if (fmt_spec.type_ && fmt_spec.type_ != 'c')
Char fill = ' '; w.write_int(value, fmt_spec);
out = w.grow_buffer(fmt_spec.width_); typedef typename BasicWriter<Char>::CharPtr CharPtr;
if (fmt_spec.align_ != ALIGN_LEFT) { CharPtr out = CharPtr();
std::fill_n(out, fmt_spec.width_ - 1, fill); if (fmt_spec.width_ > 1)
out += fmt_spec.width_ - 1; {
} else { Char fill = ' ';
std::fill_n(out + 1, fmt_spec.width_ - 1, fill); out = w.grow_buffer(fmt_spec.width_);
} if (fmt_spec.align_ != ALIGN_LEFT)
} else { {
out = w.grow_buffer(1); std::fill_n(out, fmt_spec.width_ - 1, fill);
out += fmt_spec.width_ - 1;
}
else
{
std::fill_n(out + 1, fmt_spec.width_ - 1, fill);
}
}
else
{
out = w.grow_buffer(1);
}
*out = static_cast<Char>(value);
}
/** Formats a null-terminated C string. */
void visit_cstring(const char *value)
{
if (value)
Base::visit_cstring(value);
else if (this->spec().type_ == 'p')
write_null_pointer();
else
this->write("(null)");
}
/** Formats a pointer. */
void visit_pointer(const void *value)
{
if (value)
return Base::visit_pointer(value);
this->spec().type_ = 0;
write_null_pointer();
}
/** Formats an argument of a custom (user-defined) type. */
void visit_custom(internal::Arg::CustomValue c)
{
BasicFormatter<Char> formatter(ArgList(), this->writer());
const Char format_str[] = {'}', 0};
const Char *format = format_str;
c.format(&formatter, c.value, &format);
} }
*out = static_cast<Char>(value);
}
/** Formats a null-terminated C string. */
void visit_cstring(const char *value) {
if (value)
Base::visit_cstring(value);
else if (this->spec().type_ == 'p')
write_null_pointer();
else
this->write("(null)");
}
/** Formats a pointer. */
void visit_pointer(const void *value) {
if (value)
return Base::visit_pointer(value);
this->spec().type_ = 0;
write_null_pointer();
}
/** Formats an argument of a custom (user-defined) type. */
void visit_custom(internal::Arg::CustomValue c) {
BasicFormatter<Char> formatter(ArgList(), this->writer());
const Char format_str[] = {'}', 0};
const Char *format = format_str;
c.format(&formatter, c.value, &format);
}
}; };
/** The default printf argument formatter. */ /** The default printf argument formatter. */
template <typename Char> template <typename Char>
class PrintfArgFormatter class PrintfArgFormatter
: public BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char> { : public BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char>
public: {
/** Constructs an argument formatter object. */ public:
PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s) /** Constructs an argument formatter object. */
: BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {} PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
: BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {}
}; };
/** This template formats data and writes the output to a writer. */ /** This template formats data and writes the output to a writer. */
template <typename Char, typename ArgFormatter = PrintfArgFormatter<Char> > template <typename Char, typename ArgFormatter = PrintfArgFormatter<Char> >
class PrintfFormatter : private internal::FormatterBase { class PrintfFormatter : private internal::FormatterBase
private: {
BasicWriter<Char> &writer_; private:
BasicWriter<Char> &writer_;
void parse_flags(FormatSpec &spec, const Char *&s);
void parse_flags(FormatSpec &spec, const Char *&s);
// Returns the argument with specified index or, if arg_index is equal
// to the maximum unsigned value, the next argument. // Returns the argument with specified index or, if arg_index is equal
internal::Arg get_arg( // to the maximum unsigned value, the next argument.
const Char *s, internal::Arg get_arg(
unsigned arg_index = (std::numeric_limits<unsigned>::max)()); const Char *s,
unsigned arg_index = (std::numeric_limits<unsigned>::max)());
// Parses argument index, flags and width and returns the argument index.
unsigned parse_header(const Char *&s, FormatSpec &spec); // Parses argument index, flags and width and returns the argument index.
unsigned parse_header(const Char *&s, FormatSpec &spec);
public:
/** public:
\rst /**
Constructs a ``PrintfFormatter`` object. References to the arguments and \rst
the writer are stored in the formatter object so make sure they have Constructs a ``PrintfFormatter`` object. References to the arguments and
appropriate lifetimes. the writer are stored in the formatter object so make sure they have
\endrst appropriate lifetimes.
*/ \endrst
explicit PrintfFormatter(const ArgList &args, BasicWriter<Char> &w) */
: FormatterBase(args), writer_(w) {} explicit PrintfFormatter(const ArgList &args, BasicWriter<Char> &w)
: FormatterBase(args), writer_(w) {}
/** Formats stored arguments and writes the output to the writer. */
FMT_API void format(BasicCStringRef<Char> format_str); /** Formats stored arguments and writes the output to the writer. */
FMT_API void format(BasicCStringRef<Char> format_str);
}; };
template <typename Char, typename AF> template <typename Char, typename AF>
void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s) { void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s)
for (;;) { {
switch (*s++) { for (;;)
case '-': {
spec.align_ = ALIGN_LEFT; switch (*s++)
break; {
case '+': case '-':
spec.flags_ |= SIGN_FLAG | PLUS_FLAG; spec.align_ = ALIGN_LEFT;
break; break;
case '0': case '+':
spec.fill_ = '0'; spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
break; break;
case ' ': case '0':
spec.flags_ |= SIGN_FLAG; spec.fill_ = '0';
break; break;
case '#': case ' ':
spec.flags_ |= HASH_FLAG; spec.flags_ |= SIGN_FLAG;
break; break;
default: case '#':
--s; spec.flags_ |= HASH_FLAG;
return; break;
default:
--s;
return;
}
} }
}
} }
template <typename Char, typename AF> template <typename Char, typename AF>
internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s, internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s,
unsigned arg_index) { unsigned arg_index)
(void)s; {
const char *error = 0; (void)s;
internal::Arg arg = arg_index == std::numeric_limits<unsigned>::max() ? const char *error = 0;
next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); internal::Arg arg = arg_index == std::numeric_limits<unsigned>::max() ?
if (error) next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
FMT_THROW(FormatError(!*s ? "invalid format string" : error)); if (error)
return arg; FMT_THROW(FormatError(!*s ? "invalid format string" : error));
return arg;
} }
template <typename Char, typename AF> template <typename Char, typename AF>
unsigned PrintfFormatter<Char, AF>::parse_header( unsigned PrintfFormatter<Char, AF>::parse_header(
const Char *&s, FormatSpec &spec) { const Char *&s, FormatSpec &spec)
unsigned arg_index = std::numeric_limits<unsigned>::max(); {
Char c = *s; unsigned arg_index = std::numeric_limits<unsigned>::max();
if (c >= '0' && c <= '9') { Char c = *s;
// Parse an argument index (if followed by '$') or a width possibly if (c >= '0' && c <= '9')
// preceded with '0' flag(s). {
unsigned value = internal::parse_nonnegative_int(s); // Parse an argument index (if followed by '$') or a width possibly
if (*s == '$') { // value is an argument index // preceded with '0' flag(s).
++s; unsigned value = internal::parse_nonnegative_int(s);
arg_index = value; if (*s == '$') // value is an argument index
} else { {
if (c == '0') ++s;
spec.fill_ = '0'; arg_index = value;
if (value != 0) { }
// Nonzero value means that we parsed width and don't need to else
// parse it or flags again, so return now. {
spec.width_ = value; if (c == '0')
return arg_index; spec.fill_ = '0';
} if (value != 0)
{
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
spec.width_ = value;
return arg_index;
}
}
} }
} parse_flags(spec, s);
parse_flags(spec, s); // Parse width.
// Parse width. if (*s >= '0' && *s <= '9')
if (*s >= '0' && *s <= '9') { {
spec.width_ = internal::parse_nonnegative_int(s); spec.width_ = internal::parse_nonnegative_int(s);
} else if (*s == '*') {
++s;
spec.width_ = internal::WidthHandler(spec).visit(get_arg(s));
}
return arg_index;
}
template <typename Char, typename AF>
void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) {
const Char *start = format_str.c_str();
const Char *s = start;
while (*s) {
Char c = *s++;
if (c != '%') continue;
if (*s == c) {
write(writer_, start, s);
start = ++s;
continue;
} }
write(writer_, start, s - 1); else if (*s == '*')
{
FormatSpec spec;
spec.align_ = ALIGN_RIGHT;
// Parse argument index, flags and width.
unsigned arg_index = parse_header(s, spec);
// Parse precision.
if (*s == '.') {
++s;
if ('0' <= *s && *s <= '9') {
spec.precision_ = static_cast<int>(internal::parse_nonnegative_int(s));
} else if (*s == '*') {
++s; ++s;
spec.precision_ = internal::PrecisionHandler().visit(get_arg(s)); spec.width_ = internal::WidthHandler(spec).visit(get_arg(s));
}
}
using internal::Arg;
Arg arg = get_arg(s, arg_index);
if (spec.flag(HASH_FLAG) && internal::IsZeroInt().visit(arg))
spec.flags_ &= ~internal::to_unsigned<int>(HASH_FLAG);
if (spec.fill_ == '0') {
if (arg.type <= Arg::LAST_NUMERIC_TYPE)
spec.align_ = ALIGN_NUMERIC;
else
spec.fill_ = ' '; // Ignore '0' flag for non-numeric types.
}
// Parse length and convert the argument to the required type.
using internal::ArgConverter;
switch (*s++) {
case 'h':
if (*s == 'h')
ArgConverter<signed char>(arg, *++s).visit(arg);
else
ArgConverter<short>(arg, *s).visit(arg);
break;
case 'l':
if (*s == 'l')
ArgConverter<fmt::LongLong>(arg, *++s).visit(arg);
else
ArgConverter<long>(arg, *s).visit(arg);
break;
case 'j':
ArgConverter<intmax_t>(arg, *s).visit(arg);
break;
case 'z':
ArgConverter<std::size_t>(arg, *s).visit(arg);
break;
case 't':
ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
break;
case 'L':
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break;
default:
--s;
ArgConverter<void>(arg, *s).visit(arg);
} }
return arg_index;
}
// Parse type. template <typename Char, typename AF>
if (!*s) void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
FMT_THROW(FormatError("invalid format string")); {
spec.type_ = static_cast<char>(*s++); const Char *start = format_str.c_str();
if (arg.type <= Arg::LAST_INTEGER_TYPE) { const Char *s = start;
// Normalize type. while (*s)
switch (spec.type_) { {
case 'i': case 'u': Char c = *s++;
spec.type_ = 'd'; if (c != '%') continue;
break; if (*s == c)
case 'c': {
// TODO: handle wchar_t write(writer_, start, s);
internal::CharConverter(arg).visit(arg); start = ++s;
break; continue;
} }
write(writer_, start, s - 1);
FormatSpec spec;
spec.align_ = ALIGN_RIGHT;
// Parse argument index, flags and width.
unsigned arg_index = parse_header(s, spec);
// Parse precision.
if (*s == '.')
{
++s;
if ('0' <= *s && *s <= '9')
{
spec.precision_ = static_cast<int>(internal::parse_nonnegative_int(s));
}
else if (*s == '*')
{
++s;
spec.precision_ = internal::PrecisionHandler().visit(get_arg(s));
}
}
using internal::Arg;
Arg arg = get_arg(s, arg_index);
if (spec.flag(HASH_FLAG) && internal::IsZeroInt().visit(arg))
spec.flags_ &= ~internal::to_unsigned<int>(HASH_FLAG);
if (spec.fill_ == '0')
{
if (arg.type <= Arg::LAST_NUMERIC_TYPE)
spec.align_ = ALIGN_NUMERIC;
else
spec.fill_ = ' '; // Ignore '0' flag for non-numeric types.
}
// Parse length and convert the argument to the required type.
using internal::ArgConverter;
switch (*s++)
{
case 'h':
if (*s == 'h')
ArgConverter<signed char>(arg, *++s).visit(arg);
else
ArgConverter<short>(arg, *s).visit(arg);
break;
case 'l':
if (*s == 'l')
ArgConverter<fmt::LongLong>(arg, *++s).visit(arg);
else
ArgConverter<long>(arg, *s).visit(arg);
break;
case 'j':
ArgConverter<intmax_t>(arg, *s).visit(arg);
break;
case 'z':
ArgConverter<std::size_t>(arg, *s).visit(arg);
break;
case 't':
ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
break;
case 'L':
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break;
default:
--s;
ArgConverter<void>(arg, *s).visit(arg);
}
// Parse type.
if (!*s)
FMT_THROW(FormatError("invalid format string"));
spec.type_ = static_cast<char>(*s++);
if (arg.type <= Arg::LAST_INTEGER_TYPE)
{
// Normalize type.
switch (spec.type_)
{
case 'i':
case 'u':
spec.type_ = 'd';
break;
case 'c':
// TODO: handle wchar_t
internal::CharConverter(arg).visit(arg);
break;
}
}
start = s;
// Format argument.
AF(writer_, spec).visit(arg);
} }
write(writer_, start, s);
start = s;
// Format argument.
AF(writer_, spec).visit(arg);
}
write(writer_, start, s);
} }
template <typename Char> template <typename Char>
void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) { void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args)
PrintfFormatter<Char>(args, w).format(format); {
PrintfFormatter<Char>(args, w).format(format);
} }
/** /**
...@@ -497,17 +577,19 @@ void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) { ...@@ -497,17 +577,19 @@ void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
std::string message = fmt::sprintf("The answer is %d", 42); std::string message = fmt::sprintf("The answer is %d", 42);
\endrst \endrst
*/ */
inline std::string sprintf(CStringRef format, ArgList args) { inline std::string sprintf(CStringRef format, ArgList args)
MemoryWriter w; {
printf(w, format, args); MemoryWriter w;
return w.str(); printf(w, format, args);
return w.str();
} }
FMT_VARIADIC(std::string, sprintf, CStringRef) FMT_VARIADIC(std::string, sprintf, CStringRef)
inline std::wstring sprintf(WCStringRef format, ArgList args) { inline std::wstring sprintf(WCStringRef format, ArgList args)
WMemoryWriter w; {
printf(w, format, args); WMemoryWriter w;
return w.str(); printf(w, format, args);
return w.str();
} }
FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef) FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef)
...@@ -532,8 +614,9 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) ...@@ -532,8 +614,9 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
fmt::printf("Elapsed time: %.2f seconds", 1.23); fmt::printf("Elapsed time: %.2f seconds", 1.23);
\endrst \endrst
*/ */
inline int printf(CStringRef format, ArgList args) { inline int printf(CStringRef format, ArgList args)
return fprintf(stdout, format, args); {
return fprintf(stdout, format, args);
} }
FMT_VARIADIC(int, printf, CStringRef) FMT_VARIADIC(int, printf, CStringRef)
...@@ -546,11 +629,12 @@ FMT_VARIADIC(int, printf, CStringRef) ...@@ -546,11 +629,12 @@ FMT_VARIADIC(int, printf, CStringRef)
fprintf(cerr, "Don't %s!", "panic"); fprintf(cerr, "Don't %s!", "panic");
\endrst \endrst
*/ */
inline int fprintf(std::ostream &os, CStringRef format_str, ArgList args) { inline int fprintf(std::ostream &os, CStringRef format_str, ArgList args)
MemoryWriter w; {
printf(w, format_str, args); MemoryWriter w;
internal::write(os, w); printf(w, format_str, args);
return static_cast<int>(w.size()); internal::write(os, w);
return static_cast<int>(w.size());
} }
FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef) FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef)
} // namespace fmt } // namespace fmt
......
...@@ -32,10 +32,11 @@ public: ...@@ -32,10 +32,11 @@ public:
const android_LogPriority priority = convert_to_android(msg.level); const android_LogPriority priority = convert_to_android(msg.level);
// See system/core/liblog/logger_write.c for explanation of return value // See system/core/liblog/logger_write.c for explanation of return value
const int ret = __android_log_write( const int ret = __android_log_write(
priority, _tag.c_str(), msg.formatted.c_str() priority, _tag.c_str(), msg.formatted.c_str()
); );
if (ret < 0) { if (ret < 0)
throw spdlog_ex("__android_log_write() failed", ret); {
throw spdlog_ex("__android_log_write() failed", ret);
} }
} }
......
...@@ -35,8 +35,10 @@ protected: ...@@ -35,8 +35,10 @@ protected:
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
for (auto &sink : _sinks){ for (auto &sink : _sinks)
if( sink->should_log( msg.level)){ {
if( sink->should_log( msg.level))
{
sink->log(msg); sink->log(msg);
} }
} }
......
...@@ -30,15 +30,18 @@ private: ...@@ -30,15 +30,18 @@ private:
}; };
inline bool sink::should_log(level::level_enum msg_level) const { inline bool sink::should_log(level::level_enum msg_level) const
{
return msg_level >= _level.load(std::memory_order_relaxed); return msg_level >= _level.load(std::memory_order_relaxed);
} }
inline void sink::set_level(level::level_enum log_level) { inline void sink::set_level(level::level_enum log_level)
{
_level.store(log_level); _level.store(log_level);
} }
inline level::level_enum sink::level() const { inline level::level_enum sink::level() const
{
return static_cast<spdlog::level::level_enum>(_level.load(std::memory_order_relaxed)); return static_cast<spdlog::level::level_enum>(_level.load(std::memory_order_relaxed));
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
namespace spdlog namespace spdlog
{ {
// //
// Return an existing logger or nullptr if a logger with such name doesn't exist. // Return an existing logger or nullptr if a logger with such name doesn't exist.
// example: spdlog::get("my_logger")->info("hello {}", "world"); // example: spdlog::get("my_logger")->info("hello {}", "world");
// //
...@@ -67,7 +67,7 @@ void set_sync_mode(); ...@@ -67,7 +67,7 @@ void set_sync_mode();
// //
// Create and register multi/single threaded basic file logger. // Create and register multi/single threaded basic file logger.
// Basic logger simply writes to given file without any limitatons or rotations. // Basic logger simply writes to given file without any limitatons or rotations.
// //
std::shared_ptr<logger> basic_logger_mt(const std::string& logger_name, const filename_t& filename, bool truncate = false); std::shared_ptr<logger> basic_logger_mt(const std::string& logger_name, const filename_t& filename, bool truncate = false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment