#1838 Factor out ANSI coloring.

Purpose to make the ANSI coloring  code reusable in new sink types.
pull/3112/head
Patrick Rotsaert 1 year ago
parent 3d91da64b0
commit 1d7886a27a

@ -0,0 +1,57 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#ifndef SPDLOG_HEADER_ONLY
#include <spdlog/details/ansicolors.h>
#endif
namespace spdlog {
namespace details {
SPDLOG_INLINE ansicolors::ansicolors() {
colors_.at(level::trace) = to_string_(white);
colors_.at(level::debug) = to_string_(cyan);
colors_.at(level::info) = to_string_(green);
colors_.at(level::warn) = to_string_(yellow_bold);
colors_.at(level::err) = to_string_(red_bold);
colors_.at(level::critical) = to_string_(bold_on_red);
colors_.at(level::off) = to_string_(reset);
}
SPDLOG_INLINE void ansicolors::set_color(level::level_enum color_level, string_view_t color) {
colors_.at(static_cast<size_t>(color_level)) = to_string_(color);
}
SPDLOG_INLINE std::vector<string_view_t> ansicolors::ranges(
const details::log_msg &msg, const memory_buf_t &formatted_msg) const {
std::vector<string_view_t> result{};
if (msg.color_range_end > msg.color_range_start) {
// before color range
if (msg.color_range_start > 0) {
result.push_back(string_view_t{formatted_msg.data(), msg.color_range_start});
}
// in color range
result.push_back(string_view_t{colors_.at(static_cast<size_t>(msg.level))});
result.push_back(string_view_t{formatted_msg.data() + msg.color_range_start,
msg.color_range_end - msg.color_range_start});
result.push_back(reset);
// after color range
if (msg.color_range_end < formatted_msg.size()) {
result.push_back(string_view_t{formatted_msg.data() + msg.color_range_end,
formatted_msg.size() - msg.color_range_end});
}
} else // no color
{
result.push_back(string_view_t{formatted_msg.data(), formatted_msg.size()});
}
return result;
}
SPDLOG_INLINE std::string ansicolors::to_string_(const string_view_t &sv) {
return std::string(sv.data(), sv.size());
}
} // namespace details
} // namespace spdlog

@ -0,0 +1,72 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#include <spdlog/common.h>
#include <spdlog/details/log_msg.h>
#include <array>
#include <vector>
namespace spdlog {
namespace details {
class SPDLOG_API ansicolors {
public:
explicit ansicolors();
ansicolors(const ansicolors&) = delete;
ansicolors& operator=(const ansicolors&) = delete;
void set_color(level::level_enum color_level, string_view_t color);
std::vector<string_view_t> ranges(const details::log_msg& msg,
const memory_buf_t& formatted_msg) const;
// Formatting codes
static constexpr const char* reset = "\033[m";
static constexpr const char* bold = "\033[1m";
static constexpr const char* dark = "\033[2m";
static constexpr const char* underline = "\033[4m";
static constexpr const char* blink = "\033[5m";
static constexpr const char* reverse = "\033[7m";
static constexpr const char* concealed = "\033[8m";
static constexpr const char* clear_line = "\033[K";
// Foreground colors
static constexpr const char* black = "\033[30m";
static constexpr const char* red = "\033[31m";
static constexpr const char* green = "\033[32m";
static constexpr const char* yellow = "\033[33m";
static constexpr const char* blue = "\033[34m";
static constexpr const char* magenta = "\033[35m";
static constexpr const char* cyan = "\033[36m";
static constexpr const char* white = "\033[37m";
/// Background colors
static constexpr const char* on_black = "\033[40m";
static constexpr const char* on_red = "\033[41m";
static constexpr const char* on_green = "\033[42m";
static constexpr const char* on_yellow = "\033[43m";
static constexpr const char* on_blue = "\033[44m";
static constexpr const char* on_magenta = "\033[45m";
static constexpr const char* on_cyan = "\033[46m";
static constexpr const char* on_white = "\033[47m";
/// Bold colors
static constexpr const char* yellow_bold = "\033[33m\033[1m";
static constexpr const char* red_bold = "\033[31m\033[1m";
static constexpr const char* bold_on_red = "\033[1m\033[41m";
private:
std::array<std::string, level::n_levels> colors_;
static std::string to_string_(const string_view_t& sv);
};
} // namespace details
} // namespace spdlog
#ifdef SPDLOG_HEADER_ONLY
#include "ansicolors-inl.h"
#endif

@ -17,24 +17,15 @@ template <typename ConsoleMutex>
SPDLOG_INLINE ansicolor_sink<ConsoleMutex>::ansicolor_sink(FILE *target_file, color_mode mode)
: target_file_(target_file),
mutex_(ConsoleMutex::mutex()),
formatter_(details::make_unique<spdlog::pattern_formatter>())
{
formatter_(details::make_unique<spdlog::pattern_formatter>()) {
set_color_mode(mode);
colors_.at(level::trace) = to_string_(white);
colors_.at(level::debug) = to_string_(cyan);
colors_.at(level::info) = to_string_(green);
colors_.at(level::warn) = to_string_(yellow_bold);
colors_.at(level::err) = to_string_(red_bold);
colors_.at(level::critical) = to_string_(bold_on_red);
colors_.at(level::off) = to_string_(reset);
}
template <typename ConsoleMutex>
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_color(level::level_enum color_level,
string_view_t color) {
std::lock_guard<mutex_t> lock(mutex_);
colors_.at(static_cast<size_t>(color_level)) = to_string_(color);
colors_.set_color(color_level, color);
}
template <typename ConsoleMutex>
@ -46,15 +37,10 @@ SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::log(const details::log_msg &msg
msg.color_range_end = 0;
memory_buf_t formatted;
formatter_->format(msg, formatted);
if (should_do_colors_ && msg.color_range_end > msg.color_range_start) {
// before color range
print_range_(formatted, 0, msg.color_range_start);
// in color range
print_ccode_(colors_.at(static_cast<size_t>(msg.level)));
print_range_(formatted, msg.color_range_start, msg.color_range_end);
print_ccode_(reset);
// after color range
print_range_(formatted, msg.color_range_end, formatted.size());
if (should_do_colors_) {
for (const auto &range : colors_.ranges(msg, formatted)) {
print_view_(range);
}
} else // no color
{
print_range_(formatted, 0, formatted.size());
@ -71,7 +57,7 @@ SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::flush() {
template <typename ConsoleMutex>
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_pattern(const std::string &pattern) {
std::lock_guard<mutex_t> lock(mutex_);
formatter_ = std::unique_ptr<spdlog::formatter>(new pattern_formatter(pattern));
formatter_ = details::make_unique<pattern_formatter>(pattern);
}
template <typename ConsoleMutex>
@ -105,8 +91,8 @@ SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_color_mode(color_mode mode)
}
template <typename ConsoleMutex>
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::print_ccode_(const string_view_t &color_code) {
fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_);
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::print_view_(const string_view_t &sv) {
fwrite(sv.data(), sizeof(char), sv.size(), target_file_);
}
template <typename ConsoleMutex>
@ -116,11 +102,6 @@ SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::print_range_(const memory_buf_t
fwrite(formatted.data() + start, sizeof(char), end - start, target_file_);
}
template <typename ConsoleMutex>
SPDLOG_INLINE std::string ansicolor_sink<ConsoleMutex>::to_string_(const string_view_t &sv) {
return std::string(sv.data(), sv.size());
}
// ansicolor_stdout_sink
template <typename ConsoleMutex>
SPDLOG_INLINE ansicolor_stdout_sink<ConsoleMutex>::ansicolor_stdout_sink(color_mode mode)

@ -6,6 +6,7 @@
#include <array>
#include <memory>
#include <mutex>
#include <spdlog/details/ansicolors.h>
#include <spdlog/details/console_globals.h>
#include <spdlog/details/null_mutex.h>
#include <spdlog/sinks/sink.h>
@ -44,49 +45,48 @@ public:
void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) override;
// Formatting codes
const string_view_t reset = "\033[m";
const string_view_t bold = "\033[1m";
const string_view_t dark = "\033[2m";
const string_view_t underline = "\033[4m";
const string_view_t blink = "\033[5m";
const string_view_t reverse = "\033[7m";
const string_view_t concealed = "\033[8m";
const string_view_t clear_line = "\033[K";
const string_view_t reset = details::ansicolors::reset;
const string_view_t bold = details::ansicolors::bold;
const string_view_t dark = details::ansicolors::dark;
const string_view_t underline = details::ansicolors::underline;
const string_view_t blink = details::ansicolors::blink;
const string_view_t reverse = details::ansicolors::reverse;
const string_view_t concealed = details::ansicolors::concealed;
const string_view_t clear_line = details::ansicolors::clear_line;
// Foreground colors
const string_view_t black = "\033[30m";
const string_view_t red = "\033[31m";
const string_view_t green = "\033[32m";
const string_view_t yellow = "\033[33m";
const string_view_t blue = "\033[34m";
const string_view_t magenta = "\033[35m";
const string_view_t cyan = "\033[36m";
const string_view_t white = "\033[37m";
const string_view_t black = details::ansicolors::black;
const string_view_t red = details::ansicolors::red;
const string_view_t green = details::ansicolors::green;
const string_view_t yellow = details::ansicolors::yellow;
const string_view_t blue = details::ansicolors::blue;
const string_view_t magenta = details::ansicolors::magenta;
const string_view_t cyan = details::ansicolors::cyan;
const string_view_t white = details::ansicolors::white;
/// Background colors
const string_view_t on_black = "\033[40m";
const string_view_t on_red = "\033[41m";
const string_view_t on_green = "\033[42m";
const string_view_t on_yellow = "\033[43m";
const string_view_t on_blue = "\033[44m";
const string_view_t on_magenta = "\033[45m";
const string_view_t on_cyan = "\033[46m";
const string_view_t on_white = "\033[47m";
const string_view_t on_black = details::ansicolors::on_black;
const string_view_t on_red = details::ansicolors::on_red;
const string_view_t on_green = details::ansicolors::on_green;
const string_view_t on_yellow = details::ansicolors::on_yellow;
const string_view_t on_blue = details::ansicolors::on_blue;
const string_view_t on_magenta = details::ansicolors::on_magenta;
const string_view_t on_cyan = details::ansicolors::on_cyan;
const string_view_t on_white = details::ansicolors::on_white;
/// Bold colors
const string_view_t yellow_bold = "\033[33m\033[1m";
const string_view_t red_bold = "\033[31m\033[1m";
const string_view_t bold_on_red = "\033[1m\033[41m";
const string_view_t yellow_bold = details::ansicolors::yellow_bold;
const string_view_t red_bold = details::ansicolors::red_bold;
const string_view_t bold_on_red = details::ansicolors::bold_on_red;
private:
FILE *target_file_;
mutex_t &mutex_;
details::ansicolors colors_;
bool should_do_colors_;
std::unique_ptr<spdlog::formatter> formatter_;
std::array<std::string, level::n_levels> colors_;
void print_ccode_(const string_view_t &color_code);
void print_view_(const string_view_t &sv);
void print_range_(const memory_buf_t &formatted, size_t start, size_t end);
static std::string to_string_(const string_view_t &sv);
};
template <typename ConsoleMutex>

@ -13,6 +13,7 @@
#include <spdlog/details/os-inl.h>
#include <spdlog/details/registry-inl.h>
#include <spdlog/details/rotating_file-inl.h>
#include <spdlog/details/ansicolors-inl.h>
#include <spdlog/logger-inl.h>
#include <spdlog/pattern_formatter-inl.h>
#include <spdlog/sinks/base_sink-inl.h>

Loading…
Cancel
Save