#1838 Factor out ANSI coloring.
Purpose to make the ANSI coloring code reusable in new sink types.
This commit is contained in:
parent
3d91da64b0
commit
1d7886a27a
57
include/spdlog/details/ansicolors-inl.h
Normal file
57
include/spdlog/details/ansicolors-inl.h
Normal file
@ -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
|
72
include/spdlog/details/ansicolors.h
Normal file
72
include/spdlog/details/ansicolors.h
Normal file
@ -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…
Reference in New Issue
Block a user