add style spec parsing

pull/2814/head
drakbar 2 years ago
parent af7584d818
commit 1a9966c29d

@ -726,6 +726,38 @@ private:
std::string str_;
};
#if !defined(_WIN32) && defined(SPDLOG_EXTENDED_STLYING)
// mark the color range. expect it to be in the form of "%^colored text%$"
class color_start_formatter final : public flag_formatter
{
public:
explicit color_start_formatter(padding_info padinfo, styling_info style_info)
: flag_formatter(padinfo, style_info)
{}
void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override
{
styleinfo_.is_start = true;
styleinfo_.position = dest.size();
msg.styling_ranges.push_back(styleinfo_);
}
};
class color_stop_formatter final : public flag_formatter
{
public:
explicit color_stop_formatter(padding_info padinfo)
: flag_formatter(padinfo)
{}
void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override
{
styleinfo_.is_start = false;
styleinfo_.position = dest.size();
msg.styling_ranges.push_back(styleinfo_);
}
};
#else
// mark the color range. expect it to be in the form of "%^colored text%$"
class color_start_formatter final : public flag_formatter
{
@ -749,9 +781,10 @@ public:
void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override
{
msg.color_range_end = dest.size();
msg.color_range_stop = dest.size();
}
};
#endif
// print source location
template<typename ScopedPadder>
@ -989,12 +1022,25 @@ public:
}
dest.push_back('[');
#if !defined(_WIN32) && defined(SPDLOG_EXTENDED_STLYING)
// wrap the level name with color
styleinfo_.is_start = true;
styleinfo_.position = dest.size();
msg.styling_ranges.push_back(styleinfo_);
fmt_helper::append_string_view(level::to_string_view(msg.level), dest);
styleinfo_.is_start = false;
styleinfo_.position = dest.size();
msg.styling_ranges.push_back(styleinfo_);
#else
// wrap the level name with color
msg.color_range_start = dest.size();
// fmt_helper::append_string_view(level::to_c_str(msg.level), dest);
fmt_helper::append_string_view(level::to_string_view(msg.level), dest);
msg.color_range_end = dest.size();
#endif
dest.push_back(']');
dest.push_back(' ');
@ -1103,7 +1149,11 @@ SPDLOG_INLINE std::tm pattern_formatter::get_time_(const details::log_msg &msg)
}
template<typename Padder>
#if !defined(_WIN32) && defined(SPDLOG_EXTENDED_STLYING)
SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_info padding, details::styling_info styling)
#else
SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_info padding)
#endif
{
// process custom flags
auto it = custom_handlers_.find(flag);
@ -1262,7 +1312,11 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i
break;
case ('^'): // color range start
#if !defined(_WIN32) && defined(SPDLOG_EXTENDED_STLYING)
formatters_.push_back(details::make_unique<details::color_start_formatter>(padding, styling));
#else
formatters_.push_back(details::make_unique<details::color_start_formatter>(padding));
#endif
break;
case ('$'): // color range end
@ -1388,6 +1442,99 @@ SPDLOG_INLINE details::padding_info pattern_formatter::handle_padspec_(std::stri
return details::padding_info{std::min<size_t>(width, max_width), side, truncate};
}
#if !defined(_WIN32) && defined(SPDLOG_EXTENDED_STLYING)
// Extract given style spec (e.g. %{style}^X, %{style;style}^X, ...)
// Advance the given it pass the end of the style spec found (if any)
// Return style.
SPDLOG_INLINE details::styling_info pattern_formatter::handle_stylespec_(std::string::const_iterator &it, std::string::const_iterator end)
{
using details::styling_info;
if (it == end || *it != '{' )
{ // there is no style spec, shortcuit
return styling_info{};
}
it++; // consume '{'
std::string input = static_cast<std::string>(&(*it));
size_t end_of_spec = input.find('}');
if (end_of_spec == std::string::npos)
{ // the style spec closing delimtier is not present
return styling_info{};
}
std::string full_spec_(input, 0, end_of_spec);
// need to advance the iterator the number of characters in the spec
// plus the closing delimiter '}'
size_t consumed_characters = full_spec_.length() + 1;
it += consumed_characters;
// the style spec can be delimited by semi-colons to declare
// mutliple types of styling (i.e. {fg_green;bold})
size_t insert_position = 0;
details::styles_array styles{};
if (full_spec_.find(';') != std::string::npos)
{ // spec contains multiple styles
for (auto it_s = full_spec_.begin(); it_s != full_spec_.end(); ++it_s)
{
std::string t_spec_ = static_cast<std::string>(&(*it_s));
size_t delimiter = t_spec_.find(';');
if (delimiter == std::string::npos)
{ // this is the last style in the spec
for (int i = 0; i < SPDLOG_ANSI_STLYE_COUNT; i++)
{
if (t_spec_.compare(details::style_type_table[i]) == 0)
{ // verify this style spec is valid
try
{
styles[insert_position] = details::style_type(i);
insert_position++;
}
catch (...) // user added more styles than are defined
{}
break;
}
}
break;
}
std::string s_spec_(t_spec_, 0, delimiter);
for (int i = 0; i < SPDLOG_ANSI_STLYE_COUNT; i++)
{
if (s_spec_.compare(details::style_type_table[i]) == 0)
{ // verify this style spec is valid
try
{
styles[insert_position] = details::style_type(i);
insert_position++;
}
catch (...) // user added more styles than are defined
{}
break;
}
}
// advance the iterator, the for loop will consume the semi-colon
size_t consumed_style = s_spec_.length();
it_s += consumed_style;
}
}
else
{ // style spec contains single style
for (int i = 0; i < SPDLOG_ANSI_STLYE_COUNT; i++)
{ // verify this style spec is valid
if (full_spec_.compare(details::style_type_table[i]) == 0)
{
styles[insert_position] = details::style_type(i);
break;
}
}
}
return styling_info{styles};
}
#endif
SPDLOG_INLINE void pattern_formatter::compile_pattern_(const std::string &pattern)
{
auto end = pattern.end();
@ -1404,6 +1551,21 @@ SPDLOG_INLINE void pattern_formatter::compile_pattern_(const std::string &patter
auto padding = handle_padspec_(++it, end);
#if !defined(_WIN32) && defined(SPDLOG_EXTENDED_STLYING)
auto styles = handle_stylespec_(it, end);
if (it != end)
{
if (padding.enabled())
{
handle_flag_<details::scoped_padder>(*it, padding, styles);
}
else
{
handle_flag_<details::null_scoped_padder>(*it, padding, styles);
}
}
#else
if (it != end)
{
if (padding.enabled())
@ -1415,6 +1577,7 @@ SPDLOG_INLINE void pattern_formatter::compile_pattern_(const std::string &patter
handle_flag_<details::null_scoped_padder>(*it, padding);
}
}
#endif
else
{
break;

@ -47,6 +47,37 @@ struct padding_info
bool enabled_ = false;
};
#if !defined(_WIN32) && defined(SPDLOG_EXTENDED_STLYING)
class SPDLOG_API flag_formatter
{
public:
explicit flag_formatter(padding_info padinfo)
: padinfo_(padinfo)
{}
explicit flag_formatter(padding_info padinfo, styling_info style_info)
: padinfo_(padinfo)
, styleinfo_(style_info)
{}
flag_formatter() = default;
virtual ~flag_formatter() = default;
virtual void format(const details::log_msg &msg, const std::tm &tm_time, memory_buf_t &dest) = 0;
protected:
padding_info padinfo_;
styling_info styleinfo_;
};
static const details::style_strings style_type_table
{
"null_style",
"reset", "bold", "dark", "underline", "blink", "reverse",
"fg_black", "fg_red", "fg_green", "fg_yellow", "fg_blue", "fg_magenta", "fg_cyan", "fg_white", "fg_default",
"bg_black", "bg_red", "bg_green", "bg_yellow", "bg_blue", "bg_magenta", "bg_cyan", "bg_white", "bg_default"
};
#else
class SPDLOG_API flag_formatter
{
public:
@ -61,6 +92,8 @@ protected:
padding_info padinfo_;
};
#endif
} // namespace details
class SPDLOG_API custom_flag_formatter : public details::flag_formatter
@ -112,13 +145,19 @@ private:
std::tm get_time_(const details::log_msg &msg);
template<typename Padder>
void handle_flag_(char flag, details::padding_info padding);
void handle_flag_(char flag, details::padding_info padding, details::styling_info styling);
// Extract given pad spec (e.g. %8X)
// Advance the given it pass the end of the padding spec found (if any)
// Return padding.
static details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end);
#if !defined(_WIN32) && defined(SPDLOG_EXTENDED_STLYING)
// Extract given style spec (e.g. %{style}^X, %{style;style}^X, etc...)
// Advance the given it pass the end of the style spec found (if any)
// Return style.
static details::styling_info handle_stylespec_(std::string::const_iterator &it, std::string::const_iterator end);
#endif
void compile_pattern_(const std::string &pattern);
};
} // namespace spdlog

Loading…
Cancel
Save