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/common.h> 7 #include <spdlog/details/log_msg.h> 8 #include <spdlog/details/os.h> 9 #include <spdlog/formatter.h> 10 11 #include <chrono> 12 #include <ctime> 13 #include <memory> 14 15 #include <string> 16 #include <vector> 17 #include <unordered_map> 18 19 namespace spdlog { 20 namespace details { 21 22 // padding information. 23 struct padding_info 24 { 25 enum class pad_side 26 { 27 left, 28 right, 29 center 30 }; 31 32 padding_info() = default; padding_infopadding_info33 padding_info(size_t width, padding_info::pad_side side, bool truncate) 34 : width_(width) 35 , side_(side) 36 , truncate_(truncate) 37 , enabled_(true) 38 {} 39 enabledpadding_info40 bool enabled() const 41 { 42 return enabled_; 43 } 44 size_t width_ = 0; 45 pad_side side_ = pad_side::left; 46 bool truncate_ = false; 47 bool enabled_ = false; 48 }; 49 50 class SPDLOG_API flag_formatter 51 { 52 public: flag_formatter(padding_info padinfo)53 explicit flag_formatter(padding_info padinfo) 54 : padinfo_(padinfo) 55 {} 56 flag_formatter() = default; 57 virtual ~flag_formatter() = default; 58 virtual void format(const details::log_msg &msg, const std::tm &tm_time, memory_buf_t &dest) = 0; 59 60 protected: 61 padding_info padinfo_; 62 }; 63 64 } // namespace details 65 66 class SPDLOG_API custom_flag_formatter : public details::flag_formatter 67 { 68 public: 69 virtual std::unique_ptr<custom_flag_formatter> clone() const = 0; 70 set_padding_info(details::padding_info padding)71 void set_padding_info(details::padding_info padding) 72 { 73 flag_formatter::padinfo_ = padding; 74 } 75 }; 76 77 class SPDLOG_API pattern_formatter final : public formatter 78 { 79 public: 80 using custom_flags = std::unordered_map<char, std::unique_ptr<custom_flag_formatter>>; 81 82 explicit pattern_formatter(std::string pattern, pattern_time_type time_type = pattern_time_type::local, 83 std::string eol = spdlog::details::os::default_eol, custom_flags custom_user_flags = custom_flags()); 84 85 // use default pattern is not given 86 explicit pattern_formatter(pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol); 87 88 pattern_formatter(const pattern_formatter &other) = delete; 89 pattern_formatter &operator=(const pattern_formatter &other) = delete; 90 91 std::unique_ptr<formatter> clone() const override; 92 void format(const details::log_msg &msg, memory_buf_t &dest) override; 93 94 template<typename T, typename... Args> add_flag(char flag,Args &&...args)95 pattern_formatter &add_flag(char flag, Args &&...args) 96 { 97 custom_handlers_[flag] = details::make_unique<T>(std::forward<Args>(args)...); 98 return *this; 99 } 100 void set_pattern(std::string pattern); 101 102 private: 103 std::string pattern_; 104 std::string eol_; 105 pattern_time_type pattern_time_type_; 106 std::tm cached_tm_; 107 std::chrono::seconds last_log_secs_; 108 std::vector<std::unique_ptr<details::flag_formatter>> formatters_; 109 custom_flags custom_handlers_; 110 111 std::tm get_time_(const details::log_msg &msg); 112 template<typename Padder> 113 void handle_flag_(char flag, details::padding_info padding); 114 115 // Extract given pad spec (e.g. %8X) 116 // Advance the given it pass the end of the padding spec found (if any) 117 // Return padding. 118 static details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end); 119 120 void compile_pattern_(const std::string &pattern); 121 }; 122 } // namespace spdlog 123 124 #ifdef SPDLOG_HEADER_ONLY 125 # include "pattern_formatter-inl.h" 126 #endif 127