diff --git a/include/spdlog/impl/ansicolor_sink.cpp b/include/spdlog/impl/ansicolor_sink.cpp new file mode 100644 index 00000000..97bbfd8e --- /dev/null +++ b/include/spdlog/impl/ansicolor_sink.cpp @@ -0,0 +1,105 @@ +#ifdef SPDLOG_STATIC_LIB +#include "spdlog/sinks/ansicolor_sink.h" +#endif + +#include "spdlog/details/os.h" + +template +SPDLOG_INLINE spdlog::sinks::ansicolor_sink::ansicolor_sink() + : target_file_(TargetStream::stream()) + , mutex_(ConsoleMutex::mutex()) + +{ + should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal(); + colors_[level::trace] = white; + colors_[level::debug] = cyan; + colors_[level::info] = green; + colors_[level::warn] = yellow + bold; + colors_[level::err] = red + bold; + colors_[level::critical] = bold + on_red; + colors_[level::off] = reset; +} + +template +SPDLOG_INLINE void spdlog::sinks::ansicolor_sink::set_color( + level::level_enum color_level, const std::string &color) +{ + std::lock_guard lock(mutex_); + colors_[color_level] = color; +} + +template +SPDLOG_INLINE void spdlog::sinks::ansicolor_sink::log(const details::log_msg &msg) +{ + // Wrap the originally formatted message in color codes. + // If color is not supported in the terminal, log as is instead. + std::lock_guard lock(mutex_); + + fmt::memory_buffer 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_[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()); + } + else // no color + { + print_range_(formatted, 0, formatted.size()); + } + fflush(target_file_); +} + +template +SPDLOG_INLINE void spdlog::sinks::ansicolor_sink::flush() +{ + std::lock_guard lock(mutex_); + fflush(target_file_); +} + +template +SPDLOG_INLINE void spdlog::sinks::ansicolor_sink::set_pattern(const std::string &pattern) +{ + std::lock_guard lock(mutex_); + formatter_ = std::unique_ptr(new pattern_formatter(pattern)); +} + +template +SPDLOG_INLINE void spdlog::sinks::ansicolor_sink::set_formatter( + std::unique_ptr sink_formatter) +{ + std::lock_guard lock(mutex_); + formatter_ = std::move(sink_formatter); +} + +template +SPDLOG_INLINE bool spdlog::sinks::ansicolor_sink::should_color() +{ + return should_do_colors_; +} + +template +SPDLOG_INLINE void spdlog::sinks::ansicolor_sink::print_ccode_(const std::string &color_code) +{ + fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_); +} + +template +SPDLOG_INLINE void spdlog::sinks::ansicolor_sink::print_range_( + const fmt::memory_buffer &formatted, size_t start, size_t end) +{ + fwrite(formatted.data() + start, sizeof(char), end - start, target_file_); +} + +// template instantiate stdout_mt, stdout_st +template class spdlog::sinks::ansicolor_sink; +template class spdlog::sinks::ansicolor_sink; + +// template instantiate stderr_mt, stderr_st +template class spdlog::sinks::ansicolor_sink; +template class spdlog::sinks::ansicolor_sink; diff --git a/include/spdlog/impl/base_sink.cpp b/include/spdlog/impl/base_sink.cpp index 13b16ab2..e3b5b125 100644 --- a/include/spdlog/impl/base_sink.cpp +++ b/include/spdlog/impl/base_sink.cpp @@ -10,45 +10,42 @@ template class spdlog::sinks::base_sink; #include "spdlog/common.h" #include "spdlog/details/pattern_formatter.h" -template +template void SPDLOG_INLINE spdlog::sinks::base_sink::log(const details::log_msg &msg) { std::lock_guard lock(mutex_); sink_it_(msg); } -template +template void SPDLOG_INLINE spdlog::sinks::base_sink::flush() { std::lock_guard lock(mutex_); flush_(); } -template +template void SPDLOG_INLINE spdlog::sinks::base_sink::set_pattern(const std::string &pattern) { std::lock_guard lock(mutex_); set_pattern_(pattern); } -template +template void SPDLOG_INLINE spdlog::sinks::base_sink::set_formatter(std::unique_ptr sink_formatter) { std::lock_guard lock(mutex_); set_formatter_(std::move(sink_formatter)); } -template +template void SPDLOG_INLINE spdlog::sinks::base_sink::set_pattern_(const std::string &pattern) { set_formatter_(details::make_unique(pattern)); } -template +template void SPDLOG_INLINE spdlog::sinks::base_sink::set_formatter_(std::unique_ptr sink_formatter) { formatter_ = std::move(sink_formatter); } - - - diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index 1cb797ba..44d5a287 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -11,9 +11,7 @@ #include "spdlog/details/console_globals.h" #include "spdlog/details/null_mutex.h" -#include "spdlog/details/os.h" #include "spdlog/sinks/sink.h" - #include #include #include @@ -28,36 +26,22 @@ namespace sinks { * of the message. * If no color terminal detected, omit the escape codes. */ -template +template class ansicolor_sink final : public sink { public: using mutex_t = typename ConsoleMutex::mutex_t; - ansicolor_sink() - : target_file_(TargetStream::stream()) - , mutex_(ConsoleMutex::mutex()) - - { - should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal(); - colors_[level::trace] = white; - colors_[level::debug] = cyan; - colors_[level::info] = green; - colors_[level::warn] = yellow + bold; - colors_[level::err] = red + bold; - colors_[level::critical] = bold + on_red; - colors_[level::off] = reset; - } - + ansicolor_sink(); ~ansicolor_sink() override = default; ansicolor_sink(const ansicolor_sink &other) = delete; ansicolor_sink &operator=(const ansicolor_sink &other) = delete; - - void set_color(level::level_enum color_level, const std::string &color) - { - std::lock_guard lock(mutex_); - colors_[color_level] = color; - } + void set_color(level::level_enum color_level, const std::string &color); + void log(const details::log_msg &msg) override; + void flush() override; + void set_pattern(const std::string &pattern) final; + void set_formatter(std::unique_ptr sink_formatter) override; + bool should_color(); /// Formatting codes const std::string reset = "\033[m"; @@ -89,70 +73,13 @@ public: const std::string on_cyan = "\033[46m"; const std::string on_white = "\033[47m"; - void log(const details::log_msg &msg) override - { - // Wrap the originally formatted message in color codes. - // If color is not supported in the terminal, log as is instead. - std::lock_guard lock(mutex_); - - fmt::memory_buffer 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_[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()); - } - else // no color - { - print_range_(formatted, 0, formatted.size()); - } - fflush(target_file_); - } - - void flush() override - { - std::lock_guard lock(mutex_); - fflush(target_file_); - } - - void set_pattern(const std::string &pattern) final - { - std::lock_guard lock(mutex_); - formatter_ = std::unique_ptr(new pattern_formatter(pattern)); - } - - void set_formatter(std::unique_ptr sink_formatter) override - { - std::lock_guard lock(mutex_); - formatter_ = std::move(sink_formatter); - } - - bool should_color() - { - return should_do_colors_; - } - private: - void print_ccode_(const std::string &color_code) - { - fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_); - } - void print_range_(const fmt::memory_buffer &formatted, size_t start, size_t end) - { - fwrite(formatted.data() + start, sizeof(char), end - start, target_file_); - } - FILE *target_file_; mutex_t &mutex_; - bool should_do_colors_; std::unordered_map colors_; + void print_ccode_(const std::string &color_code); + void print_range_(const fmt::memory_buffer &formatted, size_t start, size_t end); }; using ansicolor_stdout_sink_mt = ansicolor_sink; @@ -162,5 +89,8 @@ using ansicolor_stderr_sink_mt = ansicolor_sink; } // namespace sinks - } // namespace spdlog + +#ifndef SPDLOG_STATIC_LIB +#include "spdlog/impl/ansicolor_sink.cpp" +#endif \ No newline at end of file diff --git a/include/spdlog/sinks/base_sink.h b/include/spdlog/sinks/base_sink.h index 2ed1730a..000a6e20 100644 --- a/include/spdlog/sinks/base_sink.h +++ b/include/spdlog/sinks/base_sink.h @@ -25,7 +25,8 @@ public: base_sink(const base_sink &) = delete; base_sink &operator=(const base_sink &) = delete; void log(const details::log_msg &msg) final; - void flush() final;void set_pattern(const std::string &pattern) final; + void flush() final; + void set_pattern(const std::string &pattern) final; void set_formatter(std::unique_ptr sink_formatter) final; protected: @@ -38,7 +39,6 @@ protected: } // namespace sinks } // namespace spdlog - #ifndef SPDLOG_STATIC_LIB #include "spdlog/impl/base_sink.cpp" #endif \ No newline at end of file