1// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
2// Distributed under the MIT License (http://opensource.org/licenses/MIT)
3
4#pragma once
5
6#include <spdlog/details/console_globals.h>
7#include <spdlog/details/null_mutex.h>
8#include <spdlog/sinks/sink.h>
9#include <memory>
10#include <mutex>
11#include <string>
12#include <array>
13
14namespace spdlog {
15namespace sinks {
16
17/**
18 * This sink prefixes the output with an ANSI escape sequence color code
19 * depending on the severity
20 * of the message.
21 * If no color terminal detected, omit the escape codes.
22 */
23
24template<typename ConsoleMutex>
25class ansicolor_sink : public sink
26{
27public:
28 using mutex_t = typename ConsoleMutex::mutex_t;
29 ansicolor_sink(FILE *target_file, color_mode mode);
30 ~ansicolor_sink() override = default;
31
32 ansicolor_sink(const ansicolor_sink &other) = delete;
33 ansicolor_sink(ansicolor_sink &&other) = delete;
34
35 ansicolor_sink &operator=(const ansicolor_sink &other) = delete;
36 ansicolor_sink &operator=(ansicolor_sink &&other) = delete;
37
38 void set_color(level::level_enum color_level, string_view_t color);
39 void set_color_mode(color_mode mode);
40 bool should_color();
41
42 void log(const details::log_msg &msg) override;
43 void flush() override;
44 void set_pattern(const std::string &pattern) final;
45 void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) override;
46
47 // Formatting codes
48 const string_view_t reset = "\033[m";
49 const string_view_t bold = "\033[1m";
50 const string_view_t dark = "\033[2m";
51 const string_view_t underline = "\033[4m";
52 const string_view_t blink = "\033[5m";
53 const string_view_t reverse = "\033[7m";
54 const string_view_t concealed = "\033[8m";
55 const string_view_t clear_line = "\033[K";
56
57 // Foreground colors
58 const string_view_t black = "\033[30m";
59 const string_view_t red = "\033[31m";
60 const string_view_t green = "\033[32m";
61 const string_view_t yellow = "\033[33m";
62 const string_view_t blue = "\033[34m";
63 const string_view_t magenta = "\033[35m";
64 const string_view_t cyan = "\033[36m";
65 const string_view_t white = "\033[37m";
66
67 /// Background colors
68 const string_view_t on_black = "\033[40m";
69 const string_view_t on_red = "\033[41m";
70 const string_view_t on_green = "\033[42m";
71 const string_view_t on_yellow = "\033[43m";
72 const string_view_t on_blue = "\033[44m";
73 const string_view_t on_magenta = "\033[45m";
74 const string_view_t on_cyan = "\033[46m";
75 const string_view_t on_white = "\033[47m";
76
77 /// Bold colors
78 const string_view_t yellow_bold = "\033[33m\033[1m";
79 const string_view_t red_bold = "\033[31m\033[1m";
80 const string_view_t bold_on_red = "\033[1m\033[41m";
81
82private:
83 FILE *target_file_;
84 mutex_t &mutex_;
85 bool should_do_colors_;
86 std::unique_ptr<spdlog::formatter> formatter_;
87 std::array<std::string, level::n_levels> colors_;
88 void print_ccode_(const string_view_t &color_code);
89 void print_range_(const memory_buf_t &formatted, size_t start, size_t end);
90 static std::string to_string_(const string_view_t &sv);
91};
92
93template<typename ConsoleMutex>
94class ansicolor_stdout_sink : public ansicolor_sink<ConsoleMutex>
95{
96public:
97 explicit ansicolor_stdout_sink(color_mode mode = color_mode::automatic);
98};
99
100template<typename ConsoleMutex>
101class ansicolor_stderr_sink : public ansicolor_sink<ConsoleMutex>
102{
103public:
104 explicit ansicolor_stderr_sink(color_mode mode = color_mode::automatic);
105};
106
107using ansicolor_stdout_sink_mt = ansicolor_stdout_sink<details::console_mutex>;
108using ansicolor_stdout_sink_st = ansicolor_stdout_sink<details::console_nullmutex>;
109
110using ansicolor_stderr_sink_mt = ansicolor_stderr_sink<details::console_mutex>;
111using ansicolor_stderr_sink_st = ansicolor_stderr_sink<details::console_nullmutex>;
112
113} // namespace sinks
114} // namespace spdlog
115
116#ifdef SPDLOG_HEADER_ONLY
117# include "ansicolor_sink-inl.h"
118#endif
119