(third_party deps) fix #177, update bundled spdlog to 1.6.0
This commit is contained in:
		| @@ -32,7 +32,7 @@ SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg) | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         SPDLOG_THROW(spdlog_ex("async log: thread pool doesn't exist anymore")); | ||||
|         throw_spdlog_ex("async log: thread pool doesn't exist anymore"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -45,7 +45,7 @@ SPDLOG_INLINE void spdlog::async_logger::flush_() | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         SPDLOG_THROW(spdlog_ex("async flush: thread pool doesn't exist anymore")); | ||||
|         throw_spdlog_ex("async flush: thread pool doesn't exist anymore"); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -30,7 +30,7 @@ namespace details { | ||||
| class thread_pool; | ||||
| } | ||||
|  | ||||
| class async_logger final : public std::enable_shared_from_this<async_logger>, public logger | ||||
| class SPDLOG_API async_logger final : public std::enable_shared_from_this<async_logger>, public logger | ||||
| { | ||||
|     friend class details::thread_pool; | ||||
|  | ||||
|   | ||||
							
								
								
									
										45
									
								
								third_party/spdlog/include/spdlog/cfg/argv.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								third_party/spdlog/include/spdlog/cfg/argv.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. | ||||
| // Distributed under the MIT License (http://opensource.org/licenses/MIT) | ||||
|  | ||||
| #pragma once | ||||
| #include <spdlog/cfg/helpers.h> | ||||
| #include <spdlog/details/registry.h> | ||||
|  | ||||
| // | ||||
| // Init log levels using each argv entry that starts with "SPDLOG_LEVEL=" | ||||
| // | ||||
| // set all loggers to debug level: | ||||
| // example.exe "SPDLOG_LEVEL=debug" | ||||
|  | ||||
| // set logger1 to trace level | ||||
| // example.exe "SPDLOG_LEVEL=logger1=trace" | ||||
|  | ||||
| // turn off all logging except for logger1 and logger2: | ||||
| // example.exe "SPDLOG_LEVEL=off,logger1=debug,logger2=info" | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace cfg { | ||||
|  | ||||
| // search for SPDLOG_LEVEL= in the args and use it to init the levels | ||||
| void load_argv_levels(int argc, const char **argv) | ||||
| { | ||||
|     const std::string spdlog_level_prefix = "SPDLOG_LEVEL="; | ||||
|     for (int i = 1; i < argc; i++) | ||||
|     { | ||||
|         std::string arg = argv[i]; | ||||
|         if (arg.find(spdlog_level_prefix) == 0) | ||||
|         { | ||||
|             auto levels_string = arg.substr(spdlog_level_prefix.size()); | ||||
|             auto levels = helpers::extract_levels(levels_string); | ||||
|             details::registry::instance().update_levels(std::move(levels)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void load_argv_levels(int argc, char **argv) | ||||
| { | ||||
|     load_argv_levels(argc, const_cast<const char **>(argv)); | ||||
| } | ||||
|  | ||||
| } // namespace cfg | ||||
| } // namespace spdlog | ||||
							
								
								
									
										36
									
								
								third_party/spdlog/include/spdlog/cfg/env.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								third_party/spdlog/include/spdlog/cfg/env.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. | ||||
| // Distributed under the MIT License (http://opensource.org/licenses/MIT) | ||||
|  | ||||
| #pragma once | ||||
| #include <spdlog/cfg/helpers.h> | ||||
| #include <spdlog/details/registry.h> | ||||
| #include <spdlog/details/os.h> | ||||
|  | ||||
| // | ||||
| // Init levels and patterns from env variables SPDLOG_LEVEL | ||||
| // Inspired from Rust's "env_logger" crate (https://crates.io/crates/env_logger). | ||||
| // Note - fallback to "info" level on unrecognized levels | ||||
| // | ||||
| // Examples: | ||||
| // | ||||
| // set global level to debug: | ||||
| // export SPDLOG_LEVEL=debug | ||||
| // | ||||
| // turn off all logging except for logger1: | ||||
| // export SPDLOG_LEVEL="off,logger1=debug" | ||||
| // | ||||
|  | ||||
| // turn off all logging except for logger1 and logger2: | ||||
| // export SPDLOG_LEVEL="off,logger1=debug,logger2=info" | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace cfg { | ||||
| void load_env_levels() | ||||
| { | ||||
|     auto env_val = details::os::getenv("SPDLOG_LEVEL"); | ||||
|     auto levels = helpers::extract_levels(env_val); | ||||
|     details::registry::instance().update_levels(std::move(levels)); | ||||
| } | ||||
|  | ||||
| } // namespace cfg | ||||
| } // namespace spdlog | ||||
							
								
								
									
										103
									
								
								third_party/spdlog/include/spdlog/cfg/helpers-inl.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								third_party/spdlog/include/spdlog/cfg/helpers-inl.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| // 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/cfg/helpers.h> | ||||
| #endif | ||||
|  | ||||
| #include <spdlog/spdlog.h> | ||||
| #include <spdlog/details/os.h> | ||||
| #include <spdlog/details/registry.h> | ||||
|  | ||||
| #include <string> | ||||
| #include <utility> | ||||
| #include <sstream> | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace cfg { | ||||
| namespace helpers { | ||||
|  | ||||
| // inplace convert to lowercase | ||||
| inline std::string &to_lower_(std::string &str) | ||||
| { | ||||
|     std::transform( | ||||
|         str.begin(), str.end(), str.begin(), [](char ch) { return static_cast<char>((ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch); }); | ||||
|     return str; | ||||
| } | ||||
|  | ||||
| // inplace trim spaces | ||||
| inline std::string &trim_(std::string &str) | ||||
| { | ||||
|     const char *spaces = " \n\r\t"; | ||||
|     str.erase(str.find_last_not_of(spaces) + 1); | ||||
|     str.erase(0, str.find_first_not_of(spaces)); | ||||
|     return str; | ||||
| } | ||||
|  | ||||
| // return (name,value) trimmed pair from given "name=value" string. | ||||
| // return empty string on missing parts | ||||
| // "key=val" => ("key", "val") | ||||
| // " key  =  val " => ("key", "val") | ||||
| // "key=" => ("key", "") | ||||
| // "val" => ("", "val") | ||||
|  | ||||
| inline std::pair<std::string, std::string> extract_kv_(char sep, const std::string &str) | ||||
| { | ||||
|     auto n = str.find(sep); | ||||
|     std::string k, v; | ||||
|     if (n == std::string::npos) | ||||
|     { | ||||
|         v = str; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         k = str.substr(0, n); | ||||
|         v = str.substr(n + 1); | ||||
|     } | ||||
|     return std::make_pair(trim_(k), trim_(v)); | ||||
| } | ||||
|  | ||||
| // return vector of key/value pairs from sequence of "K1=V1,K2=V2,.." | ||||
| // "a=AAA,b=BBB,c=CCC,.." => {("a","AAA"),("b","BBB"),("c", "CCC"),...} | ||||
| inline std::unordered_map<std::string, std::string> extract_key_vals_(const std::string &str) | ||||
| { | ||||
|     std::string token; | ||||
|     std::istringstream token_stream(str); | ||||
|     std::unordered_map<std::string, std::string> rv{}; | ||||
|     while (std::getline(token_stream, token, ',')) | ||||
|     { | ||||
|         if (token.empty()) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
|         auto kv = extract_kv_('=', token); | ||||
|         rv[kv.first] = kv.second; | ||||
|     } | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| SPDLOG_INLINE log_levels extract_levels(const std::string &input) | ||||
| { | ||||
|     auto key_vals = extract_key_vals_(input); | ||||
|     log_levels rv; | ||||
|  | ||||
|     for (auto &name_level : key_vals) | ||||
|     { | ||||
|         auto &logger_name = name_level.first; | ||||
|         auto level_name = to_lower_(name_level.second); | ||||
|         auto level = level::from_str(level_name); | ||||
|         // fallback to "info" if unrecognized level name | ||||
|         if (level == level::off && level_name != "off") | ||||
|         { | ||||
|             level = level::info; | ||||
|         } | ||||
|         rv.set(logger_name, level); | ||||
|     } | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| } // namespace helpers | ||||
| } // namespace cfg | ||||
| } // namespace spdlog | ||||
							
								
								
									
										28
									
								
								third_party/spdlog/include/spdlog/cfg/helpers.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								third_party/spdlog/include/spdlog/cfg/helpers.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. | ||||
| // Distributed under the MIT License (http://opensource.org/licenses/MIT) | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <spdlog/cfg/log_levels.h> | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace cfg { | ||||
| namespace helpers { | ||||
| // | ||||
| // Init levels from given string | ||||
| // | ||||
| // Examples: | ||||
| // | ||||
| // set global level to debug: "debug" | ||||
| // turn off all logging except for logger1: "off,logger1=debug" | ||||
| // turn off all logging except for logger1 and logger2: "off,logger1=debug,logger2=info" | ||||
| // | ||||
| SPDLOG_API log_levels extract_levels(const std::string &txt); | ||||
| } // namespace helpers | ||||
|  | ||||
| } // namespace cfg | ||||
| } // namespace spdlog | ||||
|  | ||||
| #ifdef SPDLOG_HEADER_ONLY | ||||
| #include "helpers-inl.h" | ||||
| #endif // SPDLOG_HEADER_ONLY | ||||
							
								
								
									
										47
									
								
								third_party/spdlog/include/spdlog/cfg/log_levels.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								third_party/spdlog/include/spdlog/cfg/log_levels.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| // 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 <string> | ||||
| #include <unordered_map> | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace cfg { | ||||
| class log_levels | ||||
| { | ||||
|     std::unordered_map<std::string, spdlog::level::level_enum> levels_; | ||||
|     spdlog::level::level_enum default_level_ = level::info; | ||||
|  | ||||
| public: | ||||
|     void set(const std::string &logger_name, level::level_enum lvl) | ||||
|     { | ||||
|         if (logger_name.empty()) | ||||
|         { | ||||
|             default_level_ = lvl; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             levels_[logger_name] = lvl; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void set_default(level::level_enum lvl) | ||||
|     { | ||||
|         default_level_ = lvl; | ||||
|     } | ||||
|  | ||||
|     level::level_enum get(const std::string &logger_name) | ||||
|     { | ||||
|         auto it = levels_.find(logger_name); | ||||
|         return it != levels_.end() ? it->second : default_level_; | ||||
|     } | ||||
|  | ||||
|     level::level_enum default_level() | ||||
|     { | ||||
|         return default_level_; | ||||
|     } | ||||
| }; | ||||
| } // namespace cfg | ||||
| } // namespace spdlog | ||||
							
								
								
									
										19
									
								
								third_party/spdlog/include/spdlog/common-inl.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								third_party/spdlog/include/spdlog/common-inl.h
									
									
									
									
										vendored
									
									
								
							| @@ -34,6 +34,15 @@ SPDLOG_INLINE spdlog::level::level_enum from_str(const std::string &name) SPDLOG | ||||
|         } | ||||
|         level++; | ||||
|     } | ||||
|     // check also for "warn" and "err" before giving up.. | ||||
|     if (name == "warn") | ||||
|     { | ||||
|         return level::warn; | ||||
|     } | ||||
|     if (name == "err") | ||||
|     { | ||||
|         return level::err; | ||||
|     } | ||||
|     return level::off; | ||||
| } | ||||
| } // namespace level | ||||
| @@ -54,4 +63,14 @@ SPDLOG_INLINE const char *spdlog_ex::what() const SPDLOG_NOEXCEPT | ||||
|     return msg_.c_str(); | ||||
| } | ||||
|  | ||||
| SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno) | ||||
| { | ||||
|     SPDLOG_THROW(spdlog_ex(msg, last_errno)); | ||||
| } | ||||
|  | ||||
| SPDLOG_INLINE void throw_spdlog_ex(std::string msg) | ||||
| { | ||||
|     SPDLOG_THROW(spdlog_ex(std::move(msg))); | ||||
| } | ||||
|  | ||||
| } // namespace spdlog | ||||
|   | ||||
							
								
								
									
										35
									
								
								third_party/spdlog/include/spdlog/common.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								third_party/spdlog/include/spdlog/common.h
									
									
									
									
										vendored
									
									
								
							| @@ -15,22 +15,20 @@ | ||||
| #include <type_traits> | ||||
| #include <functional> | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| #ifndef NOMINMAX | ||||
| #define NOMINMAX // prevent windows redefining min/max | ||||
| #endif | ||||
|  | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
|  | ||||
| #include <windows.h> | ||||
| #endif //_WIN32 | ||||
|  | ||||
| #ifdef SPDLOG_COMPILED_LIB | ||||
| #undef SPDLOG_HEADER_ONLY | ||||
| #if defined(_WIN32) && defined(SPDLOG_SHARED_LIB) | ||||
| #ifdef spdlog_EXPORTS | ||||
| #define SPDLOG_API __declspec(dllexport) | ||||
| #else | ||||
| #define SPDLOG_API __declspec(dllimport) | ||||
| #endif | ||||
| #else | ||||
| #define SPDLOG_API | ||||
| #endif | ||||
| #define SPDLOG_INLINE | ||||
| #else | ||||
| #define SPDLOG_API | ||||
| #define SPDLOG_HEADER_ONLY | ||||
| #define SPDLOG_INLINE inline | ||||
| #endif | ||||
| @@ -147,6 +145,7 @@ enum level_enum | ||||
|     err = SPDLOG_LEVEL_ERROR, | ||||
|     critical = SPDLOG_LEVEL_CRITICAL, | ||||
|     off = SPDLOG_LEVEL_OFF, | ||||
|     n_levels | ||||
| }; | ||||
|  | ||||
| #if !defined(SPDLOG_LEVEL_NAMES) | ||||
| @@ -164,9 +163,9 @@ enum level_enum | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT; | ||||
| const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT; | ||||
| spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT; | ||||
|  | ||||
| using level_hasher = std::hash<int>; | ||||
| } // namespace level | ||||
| @@ -194,7 +193,7 @@ enum class pattern_time_type | ||||
| // | ||||
| // Log exception | ||||
| // | ||||
| class spdlog_ex : public std::exception | ||||
| class SPDLOG_API spdlog_ex : public std::exception | ||||
| { | ||||
| public: | ||||
|     explicit spdlog_ex(std::string msg); | ||||
| @@ -205,6 +204,9 @@ private: | ||||
|     std::string msg_; | ||||
| }; | ||||
|  | ||||
| void throw_spdlog_ex(const std::string &msg, int last_errno); | ||||
| void throw_spdlog_ex(std::string msg); | ||||
|  | ||||
| struct source_loc | ||||
| { | ||||
|     SPDLOG_CONSTEXPR source_loc() = default; | ||||
| @@ -237,7 +239,6 @@ std::unique_ptr<T> make_unique(Args &&... args) | ||||
| } | ||||
| #endif | ||||
| } // namespace details | ||||
|  | ||||
| } // namespace spdlog | ||||
|  | ||||
| #ifdef SPDLOG_HEADER_ONLY | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace details { | ||||
| class backtracer | ||||
| class SPDLOG_API backtracer | ||||
| { | ||||
|     mutable std::mutex mutex_; | ||||
|     std::atomic<bool> enabled_{false}; | ||||
|   | ||||
| @@ -43,14 +43,14 @@ SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate) | ||||
|         details::os::sleep_for_millis(open_interval_); | ||||
|     } | ||||
|  | ||||
|     SPDLOG_THROW(spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing", errno)); | ||||
|     throw_spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing", errno); | ||||
| } | ||||
|  | ||||
| SPDLOG_INLINE void file_helper::reopen(bool truncate) | ||||
| { | ||||
|     if (filename_.empty()) | ||||
|     { | ||||
|         SPDLOG_THROW(spdlog_ex("Failed re opening file - was not opened before")); | ||||
|         throw_spdlog_ex("Failed re opening file - was not opened before"); | ||||
|     } | ||||
|     this->open(filename_, truncate); | ||||
| } | ||||
| @@ -75,7 +75,7 @@ SPDLOG_INLINE void file_helper::write(const memory_buf_t &buf) | ||||
|     auto data = buf.data(); | ||||
|     if (std::fwrite(data, 1, msg_size, fd_) != msg_size) | ||||
|     { | ||||
|         SPDLOG_THROW(spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno)); | ||||
|         throw_spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -83,7 +83,7 @@ SPDLOG_INLINE size_t file_helper::size() const | ||||
| { | ||||
|     if (fd_ == nullptr) | ||||
|     { | ||||
|         SPDLOG_THROW(spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_))); | ||||
|         throw_spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_)); | ||||
|     } | ||||
|     return os::filesize(fd_); | ||||
| } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ namespace details { | ||||
| // When failing to open a file, retry several times(5) with a delay interval(10 ms). | ||||
| // Throw spdlog_ex exception on errors. | ||||
|  | ||||
| class file_helper | ||||
| class SPDLOG_API file_helper | ||||
| { | ||||
| public: | ||||
|     explicit file_helper() = default; | ||||
|   | ||||
| @@ -20,10 +20,7 @@ inline spdlog::string_view_t to_string_view(const memory_buf_t &buf) SPDLOG_NOEX | ||||
| inline void append_string_view(spdlog::string_view_t view, memory_buf_t &dest) | ||||
| { | ||||
|     auto *buf_ptr = view.data(); | ||||
|     if (buf_ptr != nullptr) | ||||
|     { | ||||
|         dest.append(buf_ptr, buf_ptr + view.size()); | ||||
|     } | ||||
|     dest.append(buf_ptr, buf_ptr + view.size()); | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| @@ -34,10 +31,10 @@ inline void append_int(T n, memory_buf_t &dest) | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| inline unsigned count_digits(T n) | ||||
| inline unsigned int count_digits(T n) | ||||
| { | ||||
|     using count_type = typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type; | ||||
|     return static_cast<unsigned>(fmt::internal::count_digits(static_cast<count_type>(n))); | ||||
|     return static_cast<unsigned int>(fmt::internal::count_digits(static_cast<count_type>(n))); | ||||
| } | ||||
|  | ||||
| inline void pad2(int n, memory_buf_t &dest) | ||||
| @@ -66,11 +63,9 @@ template<typename T> | ||||
| inline void pad_uint(T n, unsigned int width, memory_buf_t &dest) | ||||
| { | ||||
|     static_assert(std::is_unsigned<T>::value, "pad_uint must get unsigned T"); | ||||
|     auto digits = count_digits(n); | ||||
|     if (width > digits) | ||||
|     for (auto digits = count_digits(n); digits < width; digits++) | ||||
|     { | ||||
|         const char *zeroes = "0000000000000000000"; | ||||
|         dest.append(zeroes, zeroes + width - digits); | ||||
|         dest.push_back('0'); | ||||
|     } | ||||
|     append_int(n, dest); | ||||
| } | ||||
| @@ -78,7 +73,18 @@ inline void pad_uint(T n, unsigned int width, memory_buf_t &dest) | ||||
| template<typename T> | ||||
| inline void pad3(T n, memory_buf_t &dest) | ||||
| { | ||||
|     pad_uint(n, 3, dest); | ||||
|     static_assert(std::is_unsigned<T>::value, "pad3 must get unsigned T"); | ||||
|     if(n < 1000) | ||||
|     { | ||||
|         dest.push_back(static_cast<char>(n / 100 + '0')); | ||||
|         n = n % 100; | ||||
|         dest.push_back(static_cast<char>((n / 10) + '0')); | ||||
|         dest.push_back(static_cast<char>((n % 10) + '0')); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         append_int(n, dest); | ||||
|     } | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace details { | ||||
| struct log_msg | ||||
| struct SPDLOG_API log_msg | ||||
| { | ||||
|     log_msg() = default; | ||||
|     log_msg(source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg); | ||||
|   | ||||
| @@ -11,7 +11,7 @@ namespace details { | ||||
| // Extend log_msg with internal buffer to store its payload. | ||||
| // THis is needed since log_msg holds string_views that points to stack data. | ||||
|  | ||||
| class log_msg_buffer : public log_msg | ||||
| class SPDLOG_API log_msg_buffer : public log_msg | ||||
| { | ||||
|     memory_buf_t buffer; | ||||
|     void update_string_views(); | ||||
|   | ||||
| @@ -23,16 +23,9 @@ | ||||
|  | ||||
| #ifdef _WIN32 | ||||
|  | ||||
| #ifndef NOMINMAX | ||||
| #define NOMINMAX // prevent windows redefining min/max | ||||
| #endif | ||||
|  | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
| #include <io.h>      // _get_osfhandle and _isatty support | ||||
| #include <process.h> //  _get_pid support | ||||
| #include <windows.h> | ||||
| #include <spdlog/details/windows_include.h> | ||||
|  | ||||
| #ifdef __MINGW32__ | ||||
| #include <share.h> | ||||
| @@ -126,23 +119,6 @@ SPDLOG_INLINE std::tm gmtime() SPDLOG_NOEXCEPT | ||||
|     return gmtime(now_t); | ||||
| } | ||||
|  | ||||
| #ifdef SPDLOG_PREVENT_CHILD_FD | ||||
| SPDLOG_INLINE void prevent_child_fd(FILE *f) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
|     auto file_handle = reinterpret_cast<HANDLE>(_get_osfhandle(::_fileno(f))); | ||||
|     if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0)) | ||||
|         SPDLOG_THROW(spdlog_ex("SetHandleInformation failed", errno)); | ||||
| #else | ||||
|     auto fd = ::fileno(f); | ||||
|     if (::fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) | ||||
|     { | ||||
|         SPDLOG_THROW(spdlog_ex("fcntl with FD_CLOEXEC failed", errno)); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| #endif // SPDLOG_PREVENT_CHILD_FD | ||||
|  | ||||
| // fopen_s on non windows for writing | ||||
| SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode) | ||||
| { | ||||
| @@ -152,17 +128,35 @@ SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename | ||||
| #else | ||||
|     *fp = ::_fsopen((filename.c_str()), mode.c_str(), _SH_DENYNO); | ||||
| #endif | ||||
| #else // unix | ||||
|     *fp = ::fopen((filename.c_str()), mode.c_str()); | ||||
| #endif | ||||
|  | ||||
| #ifdef SPDLOG_PREVENT_CHILD_FD | ||||
|     //  prevent child processes from inheriting log file descriptors | ||||
| #if defined(SPDLOG_PREVENT_CHILD_FD) | ||||
|     if (*fp != nullptr) | ||||
|     { | ||||
|         prevent_child_fd(*fp); | ||||
|         auto file_handle = reinterpret_cast<HANDLE>(_get_osfhandle(::_fileno(*fp))); | ||||
|         if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0)) | ||||
|         { | ||||
|             ::fclose(*fp); | ||||
|             *fp = nullptr; | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
| #else // unix | ||||
| #if defined(SPDLOG_PREVENT_CHILD_FD) | ||||
|     const int mode_flag = mode == SPDLOG_FILENAME_T("ab") ? O_APPEND : O_TRUNC; | ||||
|     const int fd = ::open((filename.c_str()), O_CREAT | O_WRONLY | O_CLOEXEC | mode_flag, mode_t(0644)); | ||||
|     if (fd == -1) | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
|     *fp = ::fdopen(fd, mode.c_str()); | ||||
|     if (*fp == nullptr) | ||||
|     { | ||||
|         ::close(fd); | ||||
|     } | ||||
| #else | ||||
|     *fp = ::fopen((filename.c_str()), mode.c_str()); | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
|     return *fp == nullptr; | ||||
| } | ||||
|  | ||||
| @@ -210,7 +204,7 @@ SPDLOG_INLINE size_t filesize(FILE *f) | ||||
| { | ||||
|     if (f == nullptr) | ||||
|     { | ||||
|         SPDLOG_THROW(spdlog_ex("Failed getting file size. fd is null")); | ||||
|         throw_spdlog_ex("Failed getting file size. fd is null"); | ||||
|     } | ||||
| #if defined(_WIN32) && !defined(__CYGWIN__) | ||||
|     int fd = ::_fileno(f); | ||||
| @@ -251,7 +245,8 @@ SPDLOG_INLINE size_t filesize(FILE *f) | ||||
|     } | ||||
| #endif | ||||
| #endif | ||||
|     SPDLOG_THROW(spdlog_ex("Failed getting file size from fd", errno)); | ||||
|     throw_spdlog_ex("Failed getting file size from fd", errno); | ||||
|     return 0; // will not be reached. | ||||
| } | ||||
|  | ||||
| // Return utc offset in minutes or throw spdlog_ex on failure | ||||
| @@ -267,7 +262,7 @@ SPDLOG_INLINE int utc_minutes_offset(const std::tm &tm) | ||||
|     auto rv = ::GetDynamicTimeZoneInformation(&tzinfo); | ||||
| #endif | ||||
|     if (rv == TIME_ZONE_ID_INVALID) | ||||
|         SPDLOG_THROW(spdlog::spdlog_ex("Failed getting timezone info. ", errno)); | ||||
|         throw_spdlog_ex("Failed getting timezone info. ", errno); | ||||
|  | ||||
|     int offset = -tzinfo.Bias; | ||||
|     if (tm.tm_isdst) | ||||
| @@ -396,13 +391,13 @@ SPDLOG_INLINE int pid() SPDLOG_NOEXCEPT | ||||
| } | ||||
|  | ||||
| // Determine if the terminal supports colors | ||||
| // Source: https://github.com/agauniyal/rang/ | ||||
| // Based on: https://github.com/agauniyal/rang/ | ||||
| SPDLOG_INLINE bool is_color_terminal() SPDLOG_NOEXCEPT | ||||
| { | ||||
| #ifdef _WIN32 | ||||
|     return true; | ||||
| #else | ||||
|     static constexpr std::array<const char *, 14> Terms = { | ||||
|     static constexpr std::array<const char *, 14> terms = { | ||||
|         {"ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", "linux", "msys", "putty", "rxvt", "screen", "vt100", "xterm"}}; | ||||
|  | ||||
|     const char *env_p = std::getenv("TERM"); | ||||
| @@ -412,7 +407,7 @@ SPDLOG_INLINE bool is_color_terminal() SPDLOG_NOEXCEPT | ||||
|     } | ||||
|  | ||||
|     static const bool result = | ||||
|         std::any_of(std::begin(Terms), std::end(Terms), [&](const char *term) { return std::strstr(env_p, term) != nullptr; }); | ||||
|         std::any_of(terms.begin(), terms.end(), [&](const char *term) { return std::strstr(env_p, term) != nullptr; }); | ||||
|     return result; | ||||
| #endif | ||||
| } | ||||
| @@ -434,7 +429,7 @@ SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target) | ||||
| { | ||||
|     if (wstr.size() > static_cast<size_t>((std::numeric_limits<int>::max)())) | ||||
|     { | ||||
|         SPDLOG_THROW(spdlog::spdlog_ex("UTF-16 string is too big to be converted to UTF-8")); | ||||
|         throw_spdlog_ex("UTF-16 string is too big to be converted to UTF-8"); | ||||
|     } | ||||
|  | ||||
|     int wstr_size = static_cast<int>(wstr.size()); | ||||
| @@ -462,7 +457,7 @@ SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     SPDLOG_THROW(spdlog::spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()))); | ||||
|     throw_spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError())); | ||||
| } | ||||
| #endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) | ||||
|  | ||||
| @@ -536,6 +531,24 @@ SPDLOG_INLINE filename_t dir_name(filename_t path) | ||||
|     return pos != filename_t::npos ? path.substr(0, pos) : filename_t{}; | ||||
| } | ||||
|  | ||||
| std::string SPDLOG_INLINE getenv(const char *field) | ||||
| { | ||||
|  | ||||
| #if defined(_MSC_VER) | ||||
| #if defined(__cplusplus_winrt) | ||||
|     return std::string{}; // not supported under uwp | ||||
| #else | ||||
|     size_t len = 0; | ||||
|     char buf[128]; | ||||
|     bool ok = ::getenv_s(&len, buf, sizeof(buf), field) == 0; | ||||
|     return ok ? buf : std::string{}; | ||||
| #endif | ||||
| #else // revert to getenv | ||||
|     char *buf = ::getenv(field); | ||||
|     return buf ? buf : std::string{}; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| } // namespace os | ||||
| } // namespace details | ||||
| } // namespace spdlog | ||||
|   | ||||
							
								
								
									
										50
									
								
								third_party/spdlog/include/spdlog/details/os.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								third_party/spdlog/include/spdlog/details/os.h
									
									
									
									
										vendored
									
									
								
							| @@ -10,15 +10,15 @@ namespace spdlog { | ||||
| namespace details { | ||||
| namespace os { | ||||
|  | ||||
| spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT; | ||||
|  | ||||
| std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT; | ||||
|  | ||||
| std::tm localtime() SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API std::tm localtime() SPDLOG_NOEXCEPT; | ||||
|  | ||||
| std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT; | ||||
|  | ||||
| std::tm gmtime() SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API std::tm gmtime() SPDLOG_NOEXCEPT; | ||||
|  | ||||
| // eol definition | ||||
| #if !defined(SPDLOG_EOL) | ||||
| @@ -38,54 +38,50 @@ static const char folder_sep = '\\'; | ||||
| SPDLOG_CONSTEXPR static const char folder_sep = '/'; | ||||
| #endif | ||||
|  | ||||
| #ifdef SPDLOG_PREVENT_CHILD_FD | ||||
| void prevent_child_fd(FILE *f); | ||||
| #endif | ||||
|  | ||||
| // fopen_s on non windows for writing | ||||
| bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode); | ||||
| SPDLOG_API bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode); | ||||
|  | ||||
| // Remove filename. return 0 on success | ||||
| int remove(const filename_t &filename) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API int remove(const filename_t &filename) SPDLOG_NOEXCEPT; | ||||
|  | ||||
| // Remove file if exists. return 0 on success | ||||
| // Note: Non atomic (might return failure to delete if concurrently deleted by other process/thread) | ||||
| int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT; | ||||
|  | ||||
| int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT; | ||||
|  | ||||
| // Return if file exists. | ||||
| bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT; | ||||
|  | ||||
| // Return file size according to open FILE* object | ||||
| size_t filesize(FILE *f); | ||||
| SPDLOG_API size_t filesize(FILE *f); | ||||
|  | ||||
| // Return utc offset in minutes or throw spdlog_ex on failure | ||||
| int utc_minutes_offset(const std::tm &tm = details::os::localtime()); | ||||
| SPDLOG_API int utc_minutes_offset(const std::tm &tm = details::os::localtime()); | ||||
|  | ||||
| // Return current thread id as size_t | ||||
| // It exists because the std::this_thread::get_id() is much slower(especially | ||||
| // under VS 2013) | ||||
| size_t _thread_id() SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API size_t _thread_id() SPDLOG_NOEXCEPT; | ||||
|  | ||||
| // Return current thread id as size_t (from thread local storage) | ||||
| size_t thread_id() SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API size_t thread_id() SPDLOG_NOEXCEPT; | ||||
|  | ||||
| // This is avoid msvc issue in sleep_for that happens if the clock changes. | ||||
| // See https://github.com/gabime/spdlog/issues/609 | ||||
| void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT; | ||||
|  | ||||
| std::string filename_to_str(const filename_t &filename); | ||||
| SPDLOG_API std::string filename_to_str(const filename_t &filename); | ||||
|  | ||||
| int pid() SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API int pid() SPDLOG_NOEXCEPT; | ||||
|  | ||||
| // Determine if the terminal supports colors | ||||
| // Source: https://github.com/agauniyal/rang/ | ||||
| bool is_color_terminal() SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API bool is_color_terminal() SPDLOG_NOEXCEPT; | ||||
|  | ||||
| // Determine if the terminal attached | ||||
| // Source: https://github.com/agauniyal/rang/ | ||||
| bool in_terminal(FILE *file) SPDLOG_NOEXCEPT; | ||||
| SPDLOG_API bool in_terminal(FILE *file) SPDLOG_NOEXCEPT; | ||||
|  | ||||
| #if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) | ||||
| void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target); | ||||
| @@ -96,11 +92,15 @@ void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target); | ||||
| // "abc/" => "abc" | ||||
| // "abc" => "" | ||||
| // "abc///" => "abc//" | ||||
| filename_t dir_name(filename_t path); | ||||
| SPDLOG_API filename_t dir_name(filename_t path); | ||||
|  | ||||
| // Create a dir from the given path. | ||||
| // Return true if succeeded or if this dir already exists. | ||||
| bool create_dir(filename_t path); | ||||
| SPDLOG_API bool create_dir(filename_t path); | ||||
|  | ||||
| // non thread safe, cross platform getenv/getenv_s | ||||
| // return empty string if field not found | ||||
| SPDLOG_API std::string getenv(const char *field); | ||||
|  | ||||
| } // namespace os | ||||
| } // namespace details | ||||
|   | ||||
| @@ -17,7 +17,7 @@ | ||||
| namespace spdlog { | ||||
| namespace details { | ||||
|  | ||||
| class periodic_worker | ||||
| class SPDLOG_API periodic_worker | ||||
| { | ||||
| public: | ||||
|     periodic_worker(const std::function<void()> &callback_fun, std::chrono::seconds interval); | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
| #include <spdlog/common.h> | ||||
| #include <spdlog/details/periodic_worker.h> | ||||
| #include <spdlog/logger.h> | ||||
| #include <spdlog/details/pattern_formatter.h> | ||||
| #include <spdlog/pattern_formatter.h> | ||||
|  | ||||
| #ifndef SPDLOG_DISABLE_DEFAULT_LOGGER | ||||
| // support for the default stdout color logger | ||||
| @@ -48,6 +48,9 @@ SPDLOG_INLINE registry::registry() | ||||
|  | ||||
| #endif // SPDLOG_DISABLE_DEFAULT_LOGGER | ||||
| } | ||||
|  | ||||
| SPDLOG_INLINE registry::~registry() = default; | ||||
|  | ||||
| SPDLOG_INLINE void registry::register_logger(std::shared_ptr<logger> new_logger) | ||||
| { | ||||
|     std::lock_guard<std::mutex> lock(logger_map_mutex_); | ||||
| @@ -64,7 +67,7 @@ SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr<logger> new_logge | ||||
|         new_logger->set_error_handler(err_handler_); | ||||
|     } | ||||
|  | ||||
|     new_logger->set_level(level_); | ||||
|     new_logger->set_level(levels_.get(new_logger->name())); | ||||
|     new_logger->flush_on(flush_level_); | ||||
|  | ||||
|     if (backtrace_n_messages_ > 0) | ||||
| @@ -168,7 +171,7 @@ SPDLOG_INLINE void registry::set_level(level::level_enum log_level) | ||||
|     { | ||||
|         l.second->set_level(log_level); | ||||
|     } | ||||
|     level_ = log_level; | ||||
|     levels_.set_default(log_level); | ||||
| } | ||||
|  | ||||
| SPDLOG_INLINE void registry::flush_on(level::level_enum log_level) | ||||
| @@ -184,7 +187,7 @@ SPDLOG_INLINE void registry::flush_on(level::level_enum log_level) | ||||
| SPDLOG_INLINE void registry::flush_every(std::chrono::seconds interval) | ||||
| { | ||||
|     std::lock_guard<std::mutex> lock(flusher_mutex_); | ||||
|     std::function<void()> clbk = std::bind(®istry::flush_all, this); | ||||
|     auto clbk = [this]() { this->flush_all(); }; | ||||
|     periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval); | ||||
| } | ||||
|  | ||||
| @@ -260,6 +263,17 @@ SPDLOG_INLINE void registry::set_automatic_registration(bool automatic_registrat | ||||
|     automatic_registration_ = automatic_registration; | ||||
| } | ||||
|  | ||||
| SPDLOG_INLINE void registry::update_levels(cfg::log_levels levels) | ||||
| { | ||||
|     std::lock_guard<std::mutex> lock(logger_map_mutex_); | ||||
|     levels_ = std::move(levels); | ||||
|     for (auto &l : loggers_) | ||||
|     { | ||||
|         auto &logger = l.second; | ||||
|         logger->set_level(levels_.get(logger->name())); | ||||
|     } | ||||
| } | ||||
|  | ||||
| SPDLOG_INLINE registry ®istry::instance() | ||||
| { | ||||
|     static registry s_instance; | ||||
| @@ -270,7 +284,7 @@ SPDLOG_INLINE void registry::throw_if_exists_(const std::string &logger_name) | ||||
| { | ||||
|     if (loggers_.find(logger_name) != loggers_.end()) | ||||
|     { | ||||
|         SPDLOG_THROW(spdlog_ex("logger with name '" + logger_name + "' already exists")); | ||||
|         throw_spdlog_ex("logger with name '" + logger_name + "' already exists"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -280,5 +294,6 @@ SPDLOG_INLINE void registry::register_logger_(std::shared_ptr<logger> new_logger | ||||
|     throw_if_exists_(logger_name); | ||||
|     loggers_[logger_name] = std::move(new_logger); | ||||
| } | ||||
|  | ||||
| } // namespace details | ||||
| } // namespace spdlog | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
| // This class is thread safe | ||||
|  | ||||
| #include <spdlog/common.h> | ||||
| #include <spdlog/cfg/log_levels.h> | ||||
|  | ||||
| #include <chrono> | ||||
| #include <functional> | ||||
| @@ -24,7 +25,7 @@ namespace details { | ||||
| class thread_pool; | ||||
| class periodic_worker; | ||||
|  | ||||
| class registry | ||||
| class SPDLOG_API registry | ||||
| { | ||||
| public: | ||||
|     registry(const registry &) = delete; | ||||
| @@ -79,19 +80,21 @@ public: | ||||
|  | ||||
|     void set_automatic_registration(bool automatic_registration); | ||||
|  | ||||
|     void update_levels(cfg::log_levels levels); | ||||
|  | ||||
|     static registry &instance(); | ||||
|  | ||||
| private: | ||||
|     registry(); | ||||
|     ~registry() = default; | ||||
|     ~registry(); | ||||
|  | ||||
|     void throw_if_exists_(const std::string &logger_name); | ||||
|     void register_logger_(std::shared_ptr<logger> new_logger); | ||||
|     std::mutex logger_map_mutex_, flusher_mutex_; | ||||
|     std::recursive_mutex tp_mutex_; | ||||
|     std::unordered_map<std::string, std::shared_ptr<logger>> loggers_; | ||||
|     cfg::log_levels levels_; | ||||
|     std::unique_ptr<formatter> formatter_; | ||||
|     level::level_enum level_ = level::info; | ||||
|     level::level_enum flush_level_ = level::off; | ||||
|     void (*err_handler_)(const std::string &msg); | ||||
|     std::shared_ptr<thread_pool> tp_; | ||||
|   | ||||
							
								
								
									
										175
									
								
								third_party/spdlog/include/spdlog/details/tcp_client-windows.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								third_party/spdlog/include/spdlog/details/tcp_client-windows.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,175 @@ | ||||
| // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. | ||||
| // Distributed under the MIT License (http://opensource.org/licenses/MIT) | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| // tcp client helper | ||||
| #include <spdlog/common.h> | ||||
| #include <spdlog/details/os.h> | ||||
|  | ||||
| #include <windows.h> | ||||
| #include <winsock2.h> | ||||
| #include <ws2tcpip.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string> | ||||
|  | ||||
| #pragma comment(lib, "Ws2_32.lib") | ||||
| #pragma comment(lib, "Mswsock.lib") | ||||
| #pragma comment(lib, "AdvApi32.lib") | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace details { | ||||
| class tcp_client | ||||
| { | ||||
|     SOCKET socket_ = INVALID_SOCKET; | ||||
|  | ||||
|     static bool winsock_initialized_() | ||||
|     { | ||||
|         SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||||
|         if (s == INVALID_SOCKET) | ||||
|         { | ||||
|             return false; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             closesocket(s); | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     static void init_winsock_() | ||||
|     { | ||||
|         WSADATA wsaData; | ||||
|         auto rv = WSAStartup(MAKEWORD(2, 2), &wsaData); | ||||
|         if (rv != 0) | ||||
|         { | ||||
|             throw_winsock_error_("WSAStartup failed", ::WSAGetLastError()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     static void throw_winsock_error_(const std::string &msg, int last_error) | ||||
|     { | ||||
|         char buf[512]; | ||||
|         ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error, | ||||
|             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(char)), NULL); | ||||
|  | ||||
|         throw_spdlog_ex(fmt::format("tcp_sink - {}: {}", msg, buf)); | ||||
|     } | ||||
|  | ||||
| public: | ||||
|     bool is_connected() const | ||||
|     { | ||||
|         return socket_ != INVALID_SOCKET; | ||||
|     } | ||||
|  | ||||
|     void close() | ||||
|     { | ||||
|         ::closesocket(socket_); | ||||
|         socket_ = INVALID_SOCKET; | ||||
|         WSACleanup(); | ||||
|     } | ||||
|  | ||||
|     SOCKET fd() const | ||||
|     { | ||||
|         return socket_; | ||||
|     } | ||||
|  | ||||
|     ~tcp_client() | ||||
|     { | ||||
|         close(); | ||||
|     } | ||||
|  | ||||
|     // try to connect or throw on failure | ||||
|     void connect(const std::string &host, int port) | ||||
|     { | ||||
|         // initialize winsock if needed | ||||
|         if (!winsock_initialized_()) | ||||
|         { | ||||
|             init_winsock_(); | ||||
|         } | ||||
|  | ||||
|         if (is_connected()) | ||||
|         { | ||||
|             close(); | ||||
|         } | ||||
|         struct addrinfo hints | ||||
|         {}; | ||||
|         ZeroMemory(&hints, sizeof(hints)); | ||||
|  | ||||
|         hints.ai_family = AF_INET;       // IPv4 | ||||
|         hints.ai_socktype = SOCK_STREAM; // TCP | ||||
|         hints.ai_flags = AI_NUMERICSERV; // port passed as as numeric value | ||||
|         hints.ai_protocol = 0; | ||||
|  | ||||
|         auto port_str = std::to_string(port); | ||||
|         struct addrinfo *addrinfo_result; | ||||
|         auto rv = ::getaddrinfo(host.c_str(), port_str.c_str(), &hints, &addrinfo_result); | ||||
|         int last_error = 0; | ||||
|         if (rv != 0) | ||||
|         { | ||||
|             last_error = ::WSAGetLastError(); | ||||
|             WSACleanup(); | ||||
|             throw_winsock_error_("getaddrinfo failed", last_error); | ||||
|         } | ||||
|  | ||||
|         // Try each address until we successfully connect(2). | ||||
|  | ||||
|         for (auto *rp = addrinfo_result; rp != nullptr; rp = rp->ai_next) | ||||
|         { | ||||
|             socket_ = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); | ||||
|             if (socket_ == INVALID_SOCKET) | ||||
|             { | ||||
|                 last_error = ::WSAGetLastError(); | ||||
|                 WSACleanup(); | ||||
|                 continue; | ||||
|             } | ||||
|             if (::connect(socket_, rp->ai_addr, (int)rp->ai_addrlen) == 0) | ||||
|             { | ||||
|                 break; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 last_error = ::WSAGetLastError(); | ||||
|                 close(); | ||||
|             } | ||||
|         } | ||||
|         ::freeaddrinfo(addrinfo_result); | ||||
|         if (socket_ == INVALID_SOCKET) | ||||
|         { | ||||
|             WSACleanup(); | ||||
|             throw_winsock_error_("connect failed", last_error); | ||||
|         } | ||||
|  | ||||
|         // set TCP_NODELAY | ||||
|         int enable_flag = 1; | ||||
|         ::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, (char *)&enable_flag, sizeof(enable_flag)); | ||||
|     } | ||||
|  | ||||
|     // Send exactly n_bytes of the given data. | ||||
|     // On error close the connection and throw. | ||||
|     void send(const char *data, size_t n_bytes) | ||||
|     { | ||||
|         size_t bytes_sent = 0; | ||||
|         while (bytes_sent < n_bytes) | ||||
|         { | ||||
|             const int send_flags = 0; | ||||
|             auto write_result = ::send(socket_, data + bytes_sent, (int)(n_bytes - bytes_sent), send_flags); | ||||
|             if (write_result == SOCKET_ERROR) | ||||
|             { | ||||
|                 int last_error = ::WSAGetLastError(); | ||||
|                 close(); | ||||
|                 throw_winsock_error_("send failed", last_error); | ||||
|             } | ||||
|  | ||||
|             if (write_result == 0) // (probably should not happen but in any case..) | ||||
|             { | ||||
|                 break; | ||||
|             } | ||||
|             bytes_sent += static_cast<size_t>(write_result); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| } // namespace details | ||||
| } // namespace spdlog | ||||
							
								
								
									
										145
									
								
								third_party/spdlog/include/spdlog/details/tcp_client.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								third_party/spdlog/include/spdlog/details/tcp_client.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. | ||||
| // Distributed under the MIT License (http://opensource.org/licenses/MIT) | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| #error include tcp_client-windows.h instead | ||||
| #endif | ||||
|  | ||||
| // tcp client helper | ||||
| #include <spdlog/common.h> | ||||
| #include <spdlog/details/os.h> | ||||
|  | ||||
| #include <sys/socket.h> | ||||
| #include <arpa/inet.h> | ||||
| #include <unistd.h> | ||||
| #include <netdb.h> | ||||
| #include <netinet/tcp.h> | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace details { | ||||
| class tcp_client | ||||
| { | ||||
|     int socket_ = -1; | ||||
|  | ||||
| public: | ||||
|     bool is_connected() const | ||||
|     { | ||||
|         return socket_ != -1; | ||||
|     } | ||||
|  | ||||
|     void close() | ||||
|     { | ||||
|         if (is_connected()) | ||||
|         { | ||||
|             ::close(socket_); | ||||
|             socket_ = -1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     int fd() const | ||||
|     { | ||||
|         return socket_; | ||||
|     } | ||||
|  | ||||
|     ~tcp_client() | ||||
|     { | ||||
|         close(); | ||||
|     } | ||||
|  | ||||
|     // try to connect or throw on failure | ||||
|     void connect(const std::string &host, int port) | ||||
|     { | ||||
|         close(); | ||||
|         struct addrinfo hints | ||||
|         {}; | ||||
|         memset(&hints, 0, sizeof(struct addrinfo)); | ||||
|         hints.ai_family = AF_INET;       // IPv4 | ||||
|         hints.ai_socktype = SOCK_STREAM; // TCP | ||||
|         hints.ai_flags = AI_NUMERICSERV; // port passed as as numeric value | ||||
|         hints.ai_protocol = 0; | ||||
|  | ||||
|         auto port_str = std::to_string(port); | ||||
|         struct addrinfo *addrinfo_result; | ||||
|         auto rv = ::getaddrinfo(host.c_str(), port_str.c_str(), &hints, &addrinfo_result); | ||||
|         if (rv != 0) | ||||
|         { | ||||
|             auto msg = fmt::format("::getaddrinfo failed: {}", gai_strerror(rv)); | ||||
|             throw_spdlog_ex(msg); | ||||
|         } | ||||
|  | ||||
|         // Try each address until we successfully connect(2). | ||||
|         int last_errno = 0; | ||||
|         for (auto *rp = addrinfo_result; rp != nullptr; rp = rp->ai_next) | ||||
|         { | ||||
|             int const flags = SOCK_CLOEXEC; | ||||
|             socket_ = ::socket(rp->ai_family, rp->ai_socktype | flags, rp->ai_protocol); | ||||
|             if (socket_ == -1) | ||||
|             { | ||||
|                 last_errno = errno; | ||||
|                 continue; | ||||
|             } | ||||
|             rv = ::connect(socket_, rp->ai_addr, rp->ai_addrlen); | ||||
|             if (rv == 0) | ||||
|             { | ||||
|                 break; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 last_errno = errno; | ||||
|                 ::close(socket_); | ||||
|                 socket_ = -1; | ||||
|             } | ||||
|         } | ||||
|         ::freeaddrinfo(addrinfo_result); | ||||
|         if (socket_ == -1) | ||||
|         { | ||||
|             throw_spdlog_ex("::connect failed", last_errno); | ||||
|         } | ||||
|  | ||||
|         // set TCP_NODELAY | ||||
|         int enable_flag = 1; | ||||
|         ::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, (char *)&enable_flag, sizeof(enable_flag)); | ||||
|  | ||||
|         // prevent sigpipe on systems where MSG_NOSIGNAL is not available | ||||
| #if defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL) | ||||
|         ::setsockopt(socket_, SOL_SOCKET, SO_NOSIGPIPE, (char *)&enable_flag, sizeof(enable_flag)); | ||||
| #endif | ||||
|  | ||||
| #if !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL) | ||||
| #error "tcp_sink would raise SIGPIPE since niether SO_NOSIGPIPE nor MSG_NOSIGNAL are available" | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     // Send exactly n_bytes of the given data. | ||||
|     // On error close the connection and throw. | ||||
|     void send(const char *data, size_t n_bytes) | ||||
|     { | ||||
|         size_t bytes_sent = 0; | ||||
|         while (bytes_sent < n_bytes) | ||||
|         { | ||||
| #if defined(MSG_NOSIGNAL) | ||||
|             const int send_flags = MSG_NOSIGNAL; | ||||
| #else | ||||
|             const int send_flags = 0; | ||||
| #endif | ||||
|             auto write_result = ::send(socket_, data + bytes_sent, n_bytes - bytes_sent, send_flags); | ||||
|             if (write_result < 0) | ||||
|             { | ||||
|                 close(); | ||||
|                 throw_spdlog_ex("write(2) failed", errno); | ||||
|             } | ||||
|  | ||||
|             if (write_result == 0) // (probably should not happen but in any case..) | ||||
|             { | ||||
|                 break; | ||||
|             } | ||||
|             bytes_sent += static_cast<size_t>(write_result); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| } // namespace details | ||||
| } // namespace spdlog | ||||
| @@ -18,8 +18,8 @@ SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n, std | ||||
| { | ||||
|     if (threads_n == 0 || threads_n > 1000) | ||||
|     { | ||||
|         SPDLOG_THROW(spdlog_ex("spdlog::thread_pool(): invalid threads_n param (valid " | ||||
|                                "range is 1-1000)")); | ||||
|         throw_spdlog_ex("spdlog::thread_pool(): invalid threads_n param (valid " | ||||
|                         "range is 1-1000)"); | ||||
|     } | ||||
|     for (size_t i = 0; i < threads_n; i++) | ||||
|     { | ||||
| @@ -113,7 +113,7 @@ bool SPDLOG_INLINE thread_pool::process_next_msg_() | ||||
|     } | ||||
|  | ||||
|     default: { | ||||
|         assert(false && "Unexpected async_msg_type"); | ||||
|         assert(false); | ||||
|     } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -79,7 +79,7 @@ struct async_msg : log_msg_buffer | ||||
|     {} | ||||
| }; | ||||
|  | ||||
| class thread_pool | ||||
| class SPDLOG_API thread_pool | ||||
| { | ||||
| public: | ||||
|     using item_type = async_msg; | ||||
|   | ||||
							
								
								
									
										11
									
								
								third_party/spdlog/include/spdlog/details/windows_include.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								third_party/spdlog/include/spdlog/details/windows_include.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifndef NOMINMAX | ||||
| #define NOMINMAX // prevent windows redefining min/max | ||||
| #endif | ||||
|  | ||||
| #ifndef WIN32_LEAN_AND_MEAN | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
| #endif | ||||
|  | ||||
| #include <windows.h> | ||||
							
								
								
									
										101
									
								
								third_party/spdlog/include/spdlog/fmt/bin_to_hex.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										101
									
								
								third_party/spdlog/include/spdlog/fmt/bin_to_hex.h
									
									
									
									
										vendored
									
									
								
							| @@ -5,6 +5,8 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <cctype> | ||||
|  | ||||
| // | ||||
| // Support for logging binary data as hex | ||||
| // format flags: | ||||
| @@ -12,6 +14,7 @@ | ||||
| // {:s} - don't separate each byte with space. | ||||
| // {:p} - don't print the position on each line start. | ||||
| // {:n} - don't split the output to lines. | ||||
| // {:a} - show ASCII if :n is not set | ||||
|  | ||||
| // | ||||
| // Examples: | ||||
| @@ -20,17 +23,19 @@ | ||||
| // logger->info("Some buffer {}", spdlog::to_hex(v)); | ||||
| // char buf[128]; | ||||
| // logger->info("Some buffer {:X}", spdlog::to_hex(std::begin(buf), std::end(buf))); | ||||
| // logger->info("Some buffer {:X}", spdlog::to_hex(std::begin(buf), std::end(buf), 16)); | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace details { | ||||
|  | ||||
| template<typename It> | ||||
| class bytes_range | ||||
| class dump_info | ||||
| { | ||||
| public: | ||||
|     bytes_range(It range_begin, It range_end) | ||||
|     dump_info(It range_begin, It range_end, size_t size_per_line) | ||||
|         : begin_(range_begin) | ||||
|         , end_(range_end) | ||||
|         , size_per_line_(size_per_line) | ||||
|     {} | ||||
|  | ||||
|     It begin() const | ||||
| @@ -41,26 +46,31 @@ public: | ||||
|     { | ||||
|         return end_; | ||||
|     } | ||||
|     size_t size_per_line() const | ||||
|     { | ||||
|         return size_per_line_; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     It begin_, end_; | ||||
|     size_t size_per_line_; | ||||
| }; | ||||
| } // namespace details | ||||
|  | ||||
| // create a bytes_range that wraps the given container | ||||
| // create a dump_info that wraps the given container | ||||
| template<typename Container> | ||||
| inline details::bytes_range<typename Container::const_iterator> to_hex(const Container &container) | ||||
| inline details::dump_info<typename Container::const_iterator> to_hex(const Container &container, size_t size_per_line = 32) | ||||
| { | ||||
|     static_assert(sizeof(typename Container::value_type) == 1, "sizeof(Container::value_type) != 1"); | ||||
|     using Iter = typename Container::const_iterator; | ||||
|     return details::bytes_range<Iter>(std::begin(container), std::end(container)); | ||||
|     return details::dump_info<Iter>(std::begin(container), std::end(container), size_per_line); | ||||
| } | ||||
|  | ||||
| // create bytes_range from ranges | ||||
| // create dump_info from ranges | ||||
| template<typename It> | ||||
| inline details::bytes_range<It> to_hex(const It range_begin, const It range_end) | ||||
| inline details::dump_info<It> to_hex(const It range_begin, const It range_end, size_t size_per_line = 32) | ||||
| { | ||||
|     return details::bytes_range<It>(range_begin, range_end); | ||||
|     return details::dump_info<It>(range_begin, range_end, size_per_line); | ||||
| } | ||||
|  | ||||
| } // namespace spdlog | ||||
| @@ -68,15 +78,14 @@ inline details::bytes_range<It> to_hex(const It range_begin, const It range_end) | ||||
| namespace fmt { | ||||
|  | ||||
| template<typename T> | ||||
| struct formatter<spdlog::details::bytes_range<T>> | ||||
| struct formatter<spdlog::details::dump_info<T>> | ||||
| { | ||||
|     const std::size_t line_size = 100; | ||||
|     const char delimiter = ' '; | ||||
|  | ||||
|     bool put_newlines = true; | ||||
|     bool put_delimiters = true; | ||||
|     bool use_uppercase = false; | ||||
|     bool put_positions = true; // position on start of each line | ||||
|     bool show_ascii = false; | ||||
|  | ||||
|     // parse the format string flags | ||||
|     template<typename ParseContext> | ||||
| @@ -98,6 +107,13 @@ struct formatter<spdlog::details::bytes_range<T>> | ||||
|                 break; | ||||
|             case 'n': | ||||
|                 put_newlines = false; | ||||
|                 show_ascii = false; | ||||
|                 break; | ||||
|             case 'a': | ||||
|                 if (put_newlines) | ||||
|                 { | ||||
|                     show_ascii = true; | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
| @@ -108,53 +124,83 @@ struct formatter<spdlog::details::bytes_range<T>> | ||||
|  | ||||
|     // format the given bytes range as hex | ||||
|     template<typename FormatContext, typename Container> | ||||
|     auto format(const spdlog::details::bytes_range<Container> &the_range, FormatContext &ctx) -> decltype(ctx.out()) | ||||
|     auto format(const spdlog::details::dump_info<Container> &the_range, FormatContext &ctx) -> decltype(ctx.out()) | ||||
|     { | ||||
|         SPDLOG_CONSTEXPR const char *hex_upper = "0123456789ABCDEF"; | ||||
|         SPDLOG_CONSTEXPR const char *hex_lower = "0123456789abcdef"; | ||||
|         const char *hex_chars = use_uppercase ? hex_upper : hex_lower; | ||||
|  | ||||
|         std::size_t pos = 0; | ||||
|         std::size_t column = line_size; | ||||
| #if FMT_VERSION < 60000 | ||||
|         auto inserter = ctx.begin(); | ||||
| #else | ||||
|         auto inserter = ctx.out(); | ||||
| #endif | ||||
|  | ||||
|         for (auto &item : the_range) | ||||
|         int size_per_line = static_cast<int>(the_range.size_per_line()); | ||||
|         auto start_of_line = the_range.begin(); | ||||
|         for (auto i = the_range.begin(); i != the_range.end(); i++) | ||||
|         { | ||||
|             auto ch = static_cast<unsigned char>(item); | ||||
|             pos++; | ||||
|             auto ch = static_cast<unsigned char>(*i); | ||||
|  | ||||
|             if (put_newlines && column >= line_size) | ||||
|             if (put_newlines && (i == the_range.begin() || i - start_of_line >= size_per_line)) | ||||
|             { | ||||
|                 column = put_newline(inserter, pos); | ||||
|                 if (show_ascii && i != the_range.begin()) | ||||
|                 { | ||||
|                     *inserter++ = delimiter; | ||||
|                     *inserter++ = delimiter; | ||||
|                     for (auto j = start_of_line; j < i; j++) | ||||
|                     { | ||||
|                         auto pc = static_cast<unsigned char>(*j); | ||||
|                         *inserter++ = std::isprint(pc) ? static_cast<char>(*j) : '.'; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 put_newline(inserter, static_cast<size_t>(i - the_range.begin())); | ||||
|  | ||||
|                 // put first byte without delimiter in front of it | ||||
|                 *inserter++ = hex_chars[(ch >> 4) & 0x0f]; | ||||
|                 *inserter++ = hex_chars[ch & 0x0f]; | ||||
|                 column += 2; | ||||
|                 start_of_line = i; | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (put_delimiters) | ||||
|             { | ||||
|                 *inserter++ = delimiter; | ||||
|                 ++column; | ||||
|             } | ||||
|  | ||||
|             *inserter++ = hex_chars[(ch >> 4) & 0x0f]; | ||||
|             *inserter++ = hex_chars[ch & 0x0f]; | ||||
|             column += 2; | ||||
|         } | ||||
|         if (show_ascii) // add ascii to last line | ||||
|         { | ||||
|             if (the_range.end() - the_range.begin() > size_per_line) | ||||
|             { | ||||
|                 auto blank_num = size_per_line - (the_range.end() - start_of_line); | ||||
|                 while (blank_num-- > 0) | ||||
|                 { | ||||
|                     *inserter++ = delimiter; | ||||
|                     *inserter++ = delimiter; | ||||
|                     if (put_delimiters) | ||||
|                     { | ||||
|                         *inserter++ = delimiter; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             *inserter++ = delimiter; | ||||
|             *inserter++ = delimiter; | ||||
|             for (auto j = start_of_line; j != the_range.end(); j++) | ||||
|             { | ||||
|                 auto pc = static_cast<unsigned char>(*j); | ||||
|                 *inserter++ = std::isprint(pc) ? static_cast<char>(*j) : '.'; | ||||
|             } | ||||
|         } | ||||
|         return inserter; | ||||
|     } | ||||
|  | ||||
|     // put newline(and position header) | ||||
|     // return the next column | ||||
|     template<typename It> | ||||
|     std::size_t put_newline(It inserter, std::size_t pos) | ||||
|     void put_newline(It inserter, std::size_t pos) | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
|         *inserter++ = '\r'; | ||||
| @@ -163,12 +209,7 @@ struct formatter<spdlog::details::bytes_range<T>> | ||||
|  | ||||
|         if (put_positions) | ||||
|         { | ||||
|             fmt::format_to(inserter, "{:<04X}: ", pos - 1); | ||||
|             return 7; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return 1; | ||||
|             fmt::format_to(inserter, "{:<04X}: ", pos); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|   | ||||
| @@ -696,7 +696,7 @@ inline int to_nonnegative_int(T value, int upper) { | ||||
|  | ||||
| template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> | ||||
| inline T mod(T x, int y) { | ||||
|   return x % y; | ||||
|   return x % static_cast<T>(y); | ||||
| } | ||||
| template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)> | ||||
| inline T mod(T x, int y) { | ||||
| @@ -793,7 +793,10 @@ struct chrono_formatter { | ||||
|  | ||||
|   explicit chrono_formatter(FormatContext& ctx, OutputIt o, | ||||
|                             std::chrono::duration<Rep, Period> d) | ||||
|       : context(ctx), out(o), val(d.count()), negative(false) { | ||||
|       : context(ctx), | ||||
|         out(o), | ||||
|         val(static_cast<rep>(d.count())), | ||||
|         negative(false) { | ||||
|     if (d.count() < 0) { | ||||
|       val = 0 - val; | ||||
|       negative = true; | ||||
| @@ -1023,8 +1026,8 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> { | ||||
|     void on_error(const char* msg) { FMT_THROW(format_error(msg)); } | ||||
|     void on_fill(Char fill) { f.specs.fill[0] = fill; } | ||||
|     void on_align(align_t align) { f.specs.align = align; } | ||||
|     void on_width(unsigned width) { f.specs.width = width; } | ||||
|     void on_precision(unsigned _precision) { f.precision = _precision; } | ||||
|     void on_width(int width) { f.specs.width = width; } | ||||
|     void on_precision(int _precision) { f.precision = _precision; } | ||||
|     void end_precision() {} | ||||
|  | ||||
|     template <typename Id> void on_dynamic_width(Id arg_id) { | ||||
|   | ||||
| @@ -26,11 +26,11 @@ template <typename Char> struct format_part { | ||||
|  | ||||
|   kind part_kind; | ||||
|   union value { | ||||
|     unsigned arg_index; | ||||
|     int arg_index; | ||||
|     basic_string_view<Char> str; | ||||
|     replacement repl; | ||||
|  | ||||
|     FMT_CONSTEXPR value(unsigned index = 0) : arg_index(index) {} | ||||
|     FMT_CONSTEXPR value(int index = 0) : arg_index(index) {} | ||||
|     FMT_CONSTEXPR value(basic_string_view<Char> s) : str(s) {} | ||||
|     FMT_CONSTEXPR value(replacement r) : repl(r) {} | ||||
|   } val; | ||||
| @@ -40,7 +40,7 @@ template <typename Char> struct format_part { | ||||
|   FMT_CONSTEXPR format_part(kind k = kind::arg_index, value v = {}) | ||||
|       : part_kind(k), val(v) {} | ||||
|  | ||||
|   static FMT_CONSTEXPR format_part make_arg_index(unsigned index) { | ||||
|   static FMT_CONSTEXPR format_part make_arg_index(int index) { | ||||
|     return format_part(kind::arg_index, index); | ||||
|   } | ||||
|   static FMT_CONSTEXPR format_part make_arg_name(basic_string_view<Char> name) { | ||||
| @@ -62,7 +62,7 @@ template <typename Char> struct part_counter { | ||||
|   } | ||||
|  | ||||
|   FMT_CONSTEXPR void on_arg_id() { ++num_parts; } | ||||
|   FMT_CONSTEXPR void on_arg_id(unsigned) { ++num_parts; } | ||||
|   FMT_CONSTEXPR void on_arg_id(int) { ++num_parts; } | ||||
|   FMT_CONSTEXPR void on_arg_id(basic_string_view<Char>) { ++num_parts; } | ||||
|  | ||||
|   FMT_CONSTEXPR void on_replacement_field(const Char*) {} | ||||
| @@ -119,7 +119,7 @@ class format_string_compiler : public error_handler { | ||||
|     part_ = part::make_arg_index(parse_context_.next_arg_id()); | ||||
|   } | ||||
|  | ||||
|   FMT_CONSTEXPR void on_arg_id(unsigned id) { | ||||
|   FMT_CONSTEXPR void on_arg_id(int id) { | ||||
|     parse_context_.check_arg_id(id); | ||||
|     part_ = part::make_arg_index(id); | ||||
|   } | ||||
| @@ -512,8 +512,6 @@ template <typename CompiledFormat, typename... Args, | ||||
|                                          CompiledFormat>::value)> | ||||
| std::basic_string<Char> format(const CompiledFormat& cf, const Args&... args) { | ||||
|   basic_memory_buffer<Char> buffer; | ||||
|   using range = buffer_range<Char>; | ||||
|   using context = buffer_context<Char>; | ||||
|   cf.format(std::back_inserter(buffer), args...); | ||||
|   return to_string(buffer); | ||||
| } | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
| #include <type_traits> | ||||
|  | ||||
| // The fmt library version in the form major * 10000 + minor * 100 + patch. | ||||
| #define FMT_VERSION 60101 | ||||
| #define FMT_VERSION 60102 | ||||
|  | ||||
| #ifdef __has_feature | ||||
| #  define FMT_HAS_FEATURE(x) __has_feature(x) | ||||
| @@ -878,7 +878,7 @@ template <typename Context> struct arg_mapper { | ||||
|       FMT_ENABLE_IF( | ||||
|           std::is_constructible<std_string_view<char_type>, T>::value && | ||||
|           !std::is_constructible<basic_string_view<char_type>, T>::value && | ||||
|           !is_string<T>::value)> | ||||
|           !is_string<T>::value && !has_formatter<T, Context>::value)> | ||||
|   FMT_CONSTEXPR basic_string_view<char_type> map(const T& val) { | ||||
|     return std_string_view<char_type>(val); | ||||
|   } | ||||
| @@ -911,12 +911,14 @@ template <typename Context> struct arg_mapper { | ||||
|       map(static_cast<typename std::underlying_type<T>::type>(val))) { | ||||
|     return map(static_cast<typename std::underlying_type<T>::type>(val)); | ||||
|   } | ||||
|   template <typename T, | ||||
|             FMT_ENABLE_IF(!is_string<T>::value && !is_char<T>::value && | ||||
|                           !std::is_constructible<basic_string_view<char_type>, | ||||
|                                                  T>::value && | ||||
|                           (has_formatter<T, Context>::value || | ||||
|                            has_fallback_formatter<T, Context>::value))> | ||||
|   template < | ||||
|       typename T, | ||||
|       FMT_ENABLE_IF( | ||||
|           !is_string<T>::value && !is_char<T>::value && | ||||
|           !std::is_constructible<basic_string_view<char_type>, T>::value && | ||||
|           (has_formatter<T, Context>::value || | ||||
|            (has_fallback_formatter<T, Context>::value && | ||||
|             !std::is_constructible<std_string_view<char_type>, T>::value)))> | ||||
|   FMT_CONSTEXPR const T& map(const T& val) { | ||||
|     return val; | ||||
|   } | ||||
| @@ -1283,7 +1285,7 @@ template <typename Context> class basic_format_args { | ||||
|    */ | ||||
|   template <typename... Args> | ||||
|   basic_format_args(const format_arg_store<Context, Args...>& store) | ||||
|       : types_(static_cast<unsigned long long>(store.types)) { | ||||
|       : types_(store.types) { | ||||
|     set_data(store.data_); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -69,7 +69,8 @@ | ||||
| #  define FMT_HAS_BUILTIN(x) 0 | ||||
| #endif | ||||
|  | ||||
| #if FMT_HAS_CPP_ATTRIBUTE(fallthrough) >= 201603 && __cplusplus >= 201703 | ||||
| #if FMT_HAS_CPP_ATTRIBUTE(fallthrough) && \ | ||||
|     (__cplusplus >= 201703 || FMT_GCC_VERSION != 0) | ||||
| #  define FMT_FALLTHROUGH [[fallthrough]] | ||||
| #else | ||||
| #  define FMT_FALLTHROUGH | ||||
| @@ -801,60 +802,6 @@ template <> int count_digits<4>(internal::fallback_uintptr n); | ||||
| #  define FMT_ALWAYS_INLINE | ||||
| #endif | ||||
|  | ||||
| // Computes g = floor(log10(n)) and calls h.on<g>(n); | ||||
| template <typename Handler> FMT_ALWAYS_INLINE char* lg(uint32_t n, Handler h) { | ||||
|   return n < 100 ? n < 10 ? h.template on<0>(n) : h.template on<1>(n) | ||||
|                  : n < 1000000 | ||||
|                        ? n < 10000 ? n < 1000 ? h.template on<2>(n) | ||||
|                                               : h.template on<3>(n) | ||||
|                                    : n < 100000 ? h.template on<4>(n) | ||||
|                                                 : h.template on<5>(n) | ||||
|                        : n < 100000000 ? n < 10000000 ? h.template on<6>(n) | ||||
|                                                       : h.template on<7>(n) | ||||
|                                        : n < 1000000000 ? h.template on<8>(n) | ||||
|                                                         : h.template on<9>(n); | ||||
| } | ||||
|  | ||||
| // An lg handler that formats a decimal number. | ||||
| // Usage: lg(n, decimal_formatter(buffer)); | ||||
| class decimal_formatter { | ||||
|  private: | ||||
|   char* buffer_; | ||||
|  | ||||
|   void write_pair(unsigned N, uint32_t index) { | ||||
|     std::memcpy(buffer_ + N, data::digits + index * 2, 2); | ||||
|   } | ||||
|  | ||||
|  public: | ||||
|   explicit decimal_formatter(char* buf) : buffer_(buf) {} | ||||
|  | ||||
|   template <unsigned N> char* on(uint32_t u) { | ||||
|     if (N == 0) { | ||||
|       *buffer_ = static_cast<char>(u) + '0'; | ||||
|     } else if (N == 1) { | ||||
|       write_pair(0, u); | ||||
|     } else { | ||||
|       // The idea of using 4.32 fixed-point numbers is based on | ||||
|       // https://github.com/jeaiii/itoa | ||||
|       unsigned n = N - 1; | ||||
|       unsigned a = n / 5 * n * 53 / 16; | ||||
|       uint64_t t = | ||||
|           ((1ULL << (32 + a)) / data::zero_or_powers_of_10_32[n] + 1 - n / 9); | ||||
|       t = ((t * u) >> a) + n / 5 * 4; | ||||
|       write_pair(0, t >> 32); | ||||
|       for (unsigned i = 2; i < N; i += 2) { | ||||
|         t = 100ULL * static_cast<uint32_t>(t); | ||||
|         write_pair(i, t >> 32); | ||||
|       } | ||||
|       if (N % 2 == 0) { | ||||
|         buffer_[N] = | ||||
|             static_cast<char>((10ULL * static_cast<uint32_t>(t)) >> 32) + '0'; | ||||
|       } | ||||
|     } | ||||
|     return buffer_ += N + 1; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| #ifdef FMT_BUILTIN_CLZ | ||||
| // Optional version of count_digits for better performance on 32-bit platforms. | ||||
| inline int count_digits(uint32_t n) { | ||||
| @@ -2620,7 +2567,7 @@ class format_string_checker { | ||||
|  public: | ||||
|   explicit FMT_CONSTEXPR format_string_checker( | ||||
|       basic_string_view<Char> format_str, ErrorHandler eh) | ||||
|       : arg_id_(max_value<unsigned>()), | ||||
|       : arg_id_(-1), | ||||
|         context_(format_str, eh), | ||||
|         parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {} | ||||
|  | ||||
| @@ -2661,7 +2608,7 @@ class format_string_checker { | ||||
|   // Format specifier parsing function. | ||||
|   using parse_func = const Char* (*)(parse_context_type&); | ||||
|  | ||||
|   unsigned arg_id_; | ||||
|   int arg_id_; | ||||
|   parse_context_type context_; | ||||
|   parse_func parse_funcs_[num_args > 0 ? num_args : 1]; | ||||
| }; | ||||
|   | ||||
| @@ -333,12 +333,12 @@ template <typename OutputIt, typename Char> class basic_printf_context { | ||||
|   static void parse_flags(format_specs& specs, const Char*& it, | ||||
|                           const Char* end); | ||||
|  | ||||
|   // Returns the argument with specified index or, if arg_index is equal | ||||
|   // to the maximum unsigned value, the next argument. | ||||
|   format_arg get_arg(unsigned arg_index = internal::max_value<unsigned>()); | ||||
|   // Returns the argument with specified index or, if arg_index is -1, the next | ||||
|   // argument. | ||||
|   format_arg get_arg(int arg_index = -1); | ||||
|  | ||||
|   // Parses argument index, flags and width and returns the argument index. | ||||
|   unsigned parse_header(const Char*& it, const Char* end, format_specs& specs); | ||||
|   int parse_header(const Char*& it, const Char* end, format_specs& specs); | ||||
|  | ||||
|  public: | ||||
|   /** | ||||
| @@ -355,7 +355,7 @@ template <typename OutputIt, typename Char> class basic_printf_context { | ||||
|   OutputIt out() { return out_; } | ||||
|   void advance_to(OutputIt it) { out_ = it; } | ||||
|  | ||||
|   format_arg arg(unsigned id) const { return args_.get(id); } | ||||
|   format_arg arg(int id) const { return args_.get(id); } | ||||
|  | ||||
|   basic_format_parse_context<Char>& parse_context() { return parse_ctx_; } | ||||
|  | ||||
| @@ -397,8 +397,8 @@ void basic_printf_context<OutputIt, Char>::parse_flags(format_specs& specs, | ||||
|  | ||||
| template <typename OutputIt, typename Char> | ||||
| typename basic_printf_context<OutputIt, Char>::format_arg | ||||
| basic_printf_context<OutputIt, Char>::get_arg(unsigned arg_index) { | ||||
|   if (arg_index == internal::max_value<unsigned>()) | ||||
| basic_printf_context<OutputIt, Char>::get_arg(int arg_index) { | ||||
|   if (arg_index < 0) | ||||
|     arg_index = parse_ctx_.next_arg_id(); | ||||
|   else | ||||
|     parse_ctx_.check_arg_id(--arg_index); | ||||
| @@ -406,15 +406,15 @@ basic_printf_context<OutputIt, Char>::get_arg(unsigned arg_index) { | ||||
| } | ||||
|  | ||||
| template <typename OutputIt, typename Char> | ||||
| unsigned basic_printf_context<OutputIt, Char>::parse_header( | ||||
| int basic_printf_context<OutputIt, Char>::parse_header( | ||||
|     const Char*& it, const Char* end, format_specs& specs) { | ||||
|   unsigned arg_index = internal::max_value<unsigned>(); | ||||
|   int arg_index = -1; | ||||
|   char_type c = *it; | ||||
|   if (c >= '0' && c <= '9') { | ||||
|     // Parse an argument index (if followed by '$') or a width possibly | ||||
|     // preceded with '0' flag(s). | ||||
|     internal::error_handler eh; | ||||
|     unsigned value = parse_nonnegative_int(it, end, eh); | ||||
|     int value = parse_nonnegative_int(it, end, eh); | ||||
|     if (it != end && *it == '$') {  // value is an argument index | ||||
|       ++it; | ||||
|       arg_index = value; | ||||
| @@ -436,8 +436,8 @@ unsigned basic_printf_context<OutputIt, Char>::parse_header( | ||||
|       specs.width = parse_nonnegative_int(it, end, eh); | ||||
|     } else if (*it == '*') { | ||||
|       ++it; | ||||
|       specs.width = visit_format_arg( | ||||
|           internal::printf_width_handler<char_type>(specs), get_arg()); | ||||
|       specs.width = static_cast<int>(visit_format_arg( | ||||
|           internal::printf_width_handler<char_type>(specs), get_arg())); | ||||
|     } | ||||
|   } | ||||
|   return arg_index; | ||||
| @@ -464,7 +464,7 @@ OutputIt basic_printf_context<OutputIt, Char>::format() { | ||||
|     specs.align = align::right; | ||||
|  | ||||
|     // Parse argument index, flags and width. | ||||
|     unsigned arg_index = parse_header(it, end, specs); | ||||
|     int arg_index = parse_header(it, end, specs); | ||||
|     if (arg_index == 0) on_error("argument index out of range"); | ||||
|  | ||||
|     // Parse precision. | ||||
| @@ -473,11 +473,11 @@ OutputIt basic_printf_context<OutputIt, Char>::format() { | ||||
|       c = it != end ? *it : 0; | ||||
|       if ('0' <= c && c <= '9') { | ||||
|         internal::error_handler eh; | ||||
|         specs.precision = static_cast<int>(parse_nonnegative_int(it, end, eh)); | ||||
|         specs.precision = parse_nonnegative_int(it, end, eh); | ||||
|       } else if (c == '*') { | ||||
|         ++it; | ||||
|         specs.precision = | ||||
|             visit_format_arg(internal::printf_precision_handler(), get_arg()); | ||||
|             static_cast<int>(visit_format_arg(internal::printf_precision_handler(), get_arg())); | ||||
|       } else { | ||||
|         specs.precision = 0; | ||||
|       } | ||||
|   | ||||
							
								
								
									
										22
									
								
								third_party/spdlog/include/spdlog/fmt/fmt.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								third_party/spdlog/include/spdlog/fmt/fmt.h
									
									
									
									
										vendored
									
									
								
							| @@ -10,30 +10,16 @@ | ||||
| // By default spdlog include its own copy. | ||||
| // | ||||
|  | ||||
| #if defined(__GNUC__) || defined(__clang__) | ||||
| #pragma GCC diagnostic push | ||||
| #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" | ||||
| #pragma GCC diagnostic ignored "-Wsign-conversion" | ||||
| #endif // __GNUC__ || __clang__ | ||||
|  | ||||
|  | ||||
| #if !defined(SPDLOG_FMT_EXTERNAL) | ||||
| #ifdef SPDLOG_HEADER_ONLY | ||||
| #ifndef FMT_HEADER_ONLY | ||||
| #if !defined(SPDLOG_COMPILED_LIB) && !defined(FMT_HEADER_ONLY) | ||||
| #define FMT_HEADER_ONLY | ||||
| #endif | ||||
| #endif | ||||
| #ifndef FMT_USE_WINDOWS_H | ||||
| #define FMT_USE_WINDOWS_H 0 | ||||
| #endif | ||||
| #include "bundled/core.h" | ||||
| #include "bundled/format.h" | ||||
| #include <spdlog/fmt/bundled/core.h> | ||||
| #include <spdlog/fmt/bundled/format.h> | ||||
| #else // SPDLOG_FMT_EXTERNAL is defined - use external fmtlib | ||||
| #include <fmt/core.h> | ||||
| #include <fmt/format.h> | ||||
| #endif | ||||
|  | ||||
| // pop warnings supressions | ||||
| #if defined(__GNUC__) || defined(__clang__) | ||||
| #pragma GCC diagnostic pop | ||||
| #endif | ||||
| #endif | ||||
							
								
								
									
										6
									
								
								third_party/spdlog/include/spdlog/fmt/ostr.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								third_party/spdlog/include/spdlog/fmt/ostr.h
									
									
									
									
										vendored
									
									
								
							| @@ -7,12 +7,14 @@ | ||||
| // | ||||
| // include bundled or external copy of fmtlib's ostream support | ||||
| // | ||||
|  | ||||
| #if !defined(SPDLOG_FMT_EXTERNAL) | ||||
| #ifdef SPDLOG_HEADER_ONLY | ||||
| #ifndef FMT_HEADER_ONLY | ||||
| #define FMT_HEADER_ONLY | ||||
| #endif | ||||
| #include "bundled/ostream.h" | ||||
| #include "fmt.h" | ||||
| #endif | ||||
| #include <spdlog/fmt/bundled/ostream.h> | ||||
| #else | ||||
| #include <fmt/ostream.h> | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										14
									
								
								third_party/spdlog/include/spdlog/fwd.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								third_party/spdlog/include/spdlog/fwd.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. | ||||
| // Distributed under the MIT License (http://opensource.org/licenses/MIT) | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| namespace spdlog { | ||||
| class logger; | ||||
| class formatter; | ||||
|  | ||||
| namespace sinks { | ||||
| class sink; | ||||
| } | ||||
|  | ||||
| } // namespace spdlog | ||||
| @@ -9,7 +9,7 @@ | ||||
|  | ||||
| #include <spdlog/sinks/sink.h> | ||||
| #include <spdlog/details/backtracer.h> | ||||
| #include <spdlog/details/pattern_formatter.h> | ||||
| #include <spdlog/pattern_formatter.h> | ||||
|  | ||||
| #include <cstdio> | ||||
|  | ||||
| @@ -89,6 +89,7 @@ SPDLOG_INLINE void logger::set_formatter(std::unique_ptr<formatter> f) | ||||
|         { | ||||
|             // last element - we can be move it. | ||||
|             (*it)->set_formatter(std::move(f)); | ||||
|             break; // to prevent clang-tidy warning | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|   | ||||
							
								
								
									
										7
									
								
								third_party/spdlog/include/spdlog/logger.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								third_party/spdlog/include/spdlog/logger.h
									
									
									
									
										vendored
									
									
								
							| @@ -39,7 +39,7 @@ | ||||
|  | ||||
| namespace spdlog { | ||||
|  | ||||
| class logger | ||||
| class SPDLOG_API logger | ||||
| { | ||||
| public: | ||||
|     // Empty logger | ||||
| @@ -143,6 +143,11 @@ public: | ||||
|     // T can be statically converted to string_view | ||||
|     template<class T, typename std::enable_if<std::is_convertible<const T &, spdlog::string_view_t>::value, T>::type * = nullptr> | ||||
|     void log(source_loc loc, level::level_enum lvl, const T &msg) | ||||
|     { | ||||
|         log(loc, lvl, string_view_t{msg}); | ||||
|     } | ||||
|  | ||||
|     void log(source_loc loc, level::level_enum lvl, string_view_t msg) | ||||
|     { | ||||
|         bool log_enabled = should_log(lvl); | ||||
|         bool traceback_enabled = tracer_.enabled(); | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #ifndef SPDLOG_HEADER_ONLY | ||||
| #include <spdlog/details/pattern_formatter.h> | ||||
| #include <spdlog/pattern_formatter.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <spdlog/details/fmt_helper.h> | ||||
| @@ -90,7 +90,7 @@ struct null_scoped_padder | ||||
| }; | ||||
| 
 | ||||
| template<typename ScopedPadder> | ||||
| class name_formatter : public flag_formatter | ||||
| class name_formatter final : public flag_formatter | ||||
| { | ||||
| public: | ||||
|     explicit name_formatter(padding_info padinfo) | ||||
| @@ -106,7 +106,7 @@ public: | ||||
| 
 | ||||
| // log level appender
 | ||||
| template<typename ScopedPadder> | ||||
| class level_formatter : public flag_formatter | ||||
| class level_formatter final : public flag_formatter | ||||
| { | ||||
| public: | ||||
|     explicit level_formatter(padding_info padinfo) | ||||
| @@ -123,7 +123,7 @@ public: | ||||
| 
 | ||||
| // short log level appender
 | ||||
| template<typename ScopedPadder> | ||||
| class short_level_formatter : public flag_formatter | ||||
| class short_level_formatter final : public flag_formatter | ||||
| { | ||||
| public: | ||||
|     explicit short_level_formatter(padding_info padinfo) | ||||
| @@ -156,7 +156,7 @@ static int to12h(const tm &t) | ||||
| static std::array<const char *, 7> days{{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}}; | ||||
| 
 | ||||
| template<typename ScopedPadder> | ||||
| class a_formatter : public flag_formatter | ||||
| class a_formatter final : public flag_formatter | ||||
| { | ||||
| public: | ||||
|     explicit a_formatter(padding_info padinfo) | ||||
| @@ -194,7 +194,7 @@ public: | ||||
| static const std::array<const char *, 12> months{{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"}}; | ||||
| 
 | ||||
| template<typename ScopedPadder> | ||||
| class b_formatter : public flag_formatter | ||||
| class b_formatter final : public flag_formatter | ||||
| { | ||||
| public: | ||||
|     explicit b_formatter(padding_info padinfo) | ||||
| @@ -214,7 +214,7 @@ static const std::array<const char *, 12> full_months{ | ||||
|     {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}}; | ||||
| 
 | ||||
| template<typename ScopedPadder> | ||||
| class B_formatter : public flag_formatter | ||||
| class B_formatter final : public flag_formatter | ||||
| { | ||||
| public: | ||||
|     explicit B_formatter(padding_info padinfo) | ||||
| @@ -933,16 +933,15 @@ public: | ||||
|         dest.push_back(']'); | ||||
|         dest.push_back(' '); | ||||
| 
 | ||||
| #ifndef SPDLOG_NO_NAME | ||||
|         // append logger name if exists
 | ||||
|         if (msg.logger_name.size() > 0) | ||||
|         { | ||||
|             dest.push_back('['); | ||||
|             // fmt_helper::append_str(*msg.logger_name, dest);
 | ||||
|             fmt_helper::append_string_view(msg.logger_name, dest); | ||||
|             dest.push_back(']'); | ||||
|             dest.push_back(' '); | ||||
|         } | ||||
| #endif | ||||
| 
 | ||||
|         dest.push_back('['); | ||||
|         // wrap the level name with color
 | ||||
|         msg.color_range_start = dest.size(); | ||||
| @@ -974,11 +973,13 @@ private: | ||||
| 
 | ||||
| } // namespace details
 | ||||
| 
 | ||||
| SPDLOG_INLINE pattern_formatter::pattern_formatter(std::string pattern, pattern_time_type time_type, std::string eol) | ||||
| SPDLOG_INLINE pattern_formatter::pattern_formatter( | ||||
|     std::string pattern, pattern_time_type time_type, std::string eol, custom_flags custom_user_flags) | ||||
|     : pattern_(std::move(pattern)) | ||||
|     , eol_(std::move(eol)) | ||||
|     , pattern_time_type_(time_type) | ||||
|     , last_log_secs_(0) | ||||
|     , custom_handlers_(std::move(custom_user_flags)) | ||||
| { | ||||
|     std::memset(&cached_tm_, 0, sizeof(cached_tm_)); | ||||
|     compile_pattern_(pattern_); | ||||
| @@ -997,7 +998,12 @@ SPDLOG_INLINE pattern_formatter::pattern_formatter(pattern_time_type time_type, | ||||
| 
 | ||||
| SPDLOG_INLINE std::unique_ptr<formatter> pattern_formatter::clone() const | ||||
| { | ||||
|     return details::make_unique<pattern_formatter>(pattern_, pattern_time_type_, eol_); | ||||
|     custom_flags cloned_custom_formatters; | ||||
|     for (auto &it : custom_handlers_) | ||||
|     { | ||||
|         cloned_custom_formatters[it.first] = it.second->clone(); | ||||
|     } | ||||
|     return details::make_unique<pattern_formatter>(pattern_, pattern_time_type_, eol_, std::move(cloned_custom_formatters)); | ||||
| } | ||||
| 
 | ||||
| SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory_buf_t &dest) | ||||
| @@ -1017,6 +1023,12 @@ SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory | ||||
|     details::fmt_helper::append_string_view(eol_, dest); | ||||
| } | ||||
| 
 | ||||
| SPDLOG_INLINE void pattern_formatter::set_pattern(std::string pattern) | ||||
| { | ||||
|     pattern_ = std::move(pattern); | ||||
|     compile_pattern_(pattern_); | ||||
| } | ||||
| 
 | ||||
| SPDLOG_INLINE std::tm pattern_formatter::get_time_(const details::log_msg &msg) | ||||
| { | ||||
|     if (pattern_time_type_ == pattern_time_type::local) | ||||
| @@ -1029,9 +1041,19 @@ SPDLOG_INLINE std::tm pattern_formatter::get_time_(const details::log_msg &msg) | ||||
| template<typename Padder> | ||||
| SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_info padding) | ||||
| { | ||||
|     // process custom flags
 | ||||
|     auto it = custom_handlers_.find(flag); | ||||
|     if (it != custom_handlers_.end()) | ||||
|     { | ||||
|         auto custom_handler = it->second->clone(); | ||||
|         custom_handler->set_padding_info(padding); | ||||
|         formatters_.push_back(std::move(custom_handler)); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // process built-in flags
 | ||||
|     switch (flag) | ||||
|     { | ||||
| 
 | ||||
|     case ('+'): // default formatter
 | ||||
|         formatters_.push_back(details::make_unique<details::full_formatter>(padding)); | ||||
|         break; | ||||
| @@ -14,6 +14,7 @@ | ||||
| 
 | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <unordered_map> | ||||
| 
 | ||||
| namespace spdlog { | ||||
| namespace details { | ||||
| @@ -40,13 +41,13 @@ struct padding_info | ||||
|     { | ||||
|         return enabled_; | ||||
|     } | ||||
|     const size_t width_ = 0; | ||||
|     const pad_side side_ = left; | ||||
|     size_t width_ = 0; | ||||
|     pad_side side_ = left; | ||||
|     bool truncate_ = false; | ||||
|     bool enabled_ = false; | ||||
| }; | ||||
| 
 | ||||
| class flag_formatter | ||||
| class SPDLOG_API flag_formatter | ||||
| { | ||||
| public: | ||||
|     explicit flag_formatter(padding_info padinfo) | ||||
| @@ -62,11 +63,24 @@ protected: | ||||
| 
 | ||||
| } // namespace details
 | ||||
| 
 | ||||
| class pattern_formatter final : public formatter | ||||
| class SPDLOG_API custom_flag_formatter : public details::flag_formatter | ||||
| { | ||||
| public: | ||||
|     explicit pattern_formatter( | ||||
|         std::string pattern, pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol); | ||||
|     virtual std::unique_ptr<custom_flag_formatter> clone() const = 0; | ||||
| 
 | ||||
|     void set_padding_info(details::padding_info padding) | ||||
|     { | ||||
|         flag_formatter::padinfo_ = padding; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| class SPDLOG_API pattern_formatter final : public formatter | ||||
| { | ||||
| public: | ||||
|     using custom_flags = std::unordered_map<char, std::unique_ptr<custom_flag_formatter>>; | ||||
| 
 | ||||
|     explicit pattern_formatter(std::string pattern, pattern_time_type time_type = pattern_time_type::local, | ||||
|         std::string eol = spdlog::details::os::default_eol, custom_flags custom_user_flags = {}); | ||||
| 
 | ||||
|     // use default pattern is not given
 | ||||
|     explicit pattern_formatter(pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol); | ||||
| @@ -77,6 +91,14 @@ public: | ||||
|     std::unique_ptr<formatter> clone() const override; | ||||
|     void format(const details::log_msg &msg, memory_buf_t &dest) override; | ||||
| 
 | ||||
|     template<typename T, typename... Args> | ||||
|     pattern_formatter &add_flag(char flag, const Args &... args) | ||||
|     { | ||||
|         custom_handlers_[flag] = details::make_unique<T>(args...); | ||||
|         return *this; | ||||
|     } | ||||
|     void set_pattern(std::string pattern); | ||||
| 
 | ||||
| private: | ||||
|     std::string pattern_; | ||||
|     std::string eol_; | ||||
| @@ -84,6 +106,7 @@ private: | ||||
|     std::tm cached_tm_; | ||||
|     std::chrono::seconds last_log_secs_; | ||||
|     std::vector<std::unique_ptr<details::flag_formatter>> formatters_; | ||||
|     custom_flags custom_handlers_; | ||||
| 
 | ||||
|     std::tm get_time_(const details::log_msg &msg); | ||||
|     template<typename Padder> | ||||
| @@ -92,7 +115,7 @@ private: | ||||
|     // Extract given pad spec (e.g. %8X)
 | ||||
|     // Advance the given it pass the end of the padding spec found (if any)
 | ||||
|     // Return padding.
 | ||||
|     details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end); | ||||
|     static details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end); | ||||
| 
 | ||||
|     void compile_pattern_(const std::string &pattern); | ||||
| }; | ||||
| @@ -64,7 +64,7 @@ protected: | ||||
|  | ||||
|         if (ret < 0) | ||||
|         { | ||||
|             SPDLOG_THROW(spdlog_ex("__android_log_write() failed", ret)); | ||||
|             throw_spdlog_ex("__android_log_write() failed", ret); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
| #include <spdlog/sinks/ansicolor_sink.h> | ||||
| #endif | ||||
|  | ||||
| #include <spdlog/details/pattern_formatter.h> | ||||
| #include <spdlog/pattern_formatter.h> | ||||
| #include <spdlog/details/os.h> | ||||
|  | ||||
| namespace spdlog { | ||||
| @@ -43,7 +43,8 @@ SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::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<mutex_t> lock(mutex_); | ||||
|  | ||||
|     msg.color_range_start = 0; | ||||
|     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) | ||||
| @@ -111,7 +112,7 @@ 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(string_view_t::char_type), color_code.size(), target_file_); | ||||
|     fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_); | ||||
| } | ||||
|  | ||||
| template<typename ConsoleMutex> | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| #include <memory> | ||||
| #include <mutex> | ||||
| #include <string> | ||||
| #include <unordered_map> | ||||
| #include <array> | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace sinks { | ||||
| @@ -30,7 +30,11 @@ public: | ||||
|     ~ansicolor_sink() override = default; | ||||
|  | ||||
|     ansicolor_sink(const ansicolor_sink &other) = delete; | ||||
|     ansicolor_sink(ansicolor_sink &&other) = delete; | ||||
|  | ||||
|     ansicolor_sink &operator=(const ansicolor_sink &other) = delete; | ||||
|     ansicolor_sink &operator=(ansicolor_sink &&other) = delete; | ||||
|  | ||||
|     void set_color(level::level_enum color_level, string_view_t color); | ||||
|     void set_color_mode(color_mode mode); | ||||
|     bool should_color(); | ||||
| @@ -80,7 +84,7 @@ private: | ||||
|     mutex_t &mutex_; | ||||
|     bool should_do_colors_; | ||||
|     std::unique_ptr<spdlog::formatter> formatter_; | ||||
|     std::unordered_map<level::level_enum, string_view_t, level::level_hasher> colors_; | ||||
|     std::array<string_view_t, level::n_levels> colors_; | ||||
|     void print_ccode_(const string_view_t &color_code); | ||||
|     void print_range_(const memory_buf_t &formatted, size_t start, size_t end); | ||||
| }; | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| #endif | ||||
|  | ||||
| #include <spdlog/common.h> | ||||
| #include <spdlog/details/pattern_formatter.h> | ||||
| #include <spdlog/pattern_formatter.h> | ||||
|  | ||||
| #include <memory> | ||||
|  | ||||
|   | ||||
| @@ -21,8 +21,14 @@ class base_sink : public sink | ||||
| public: | ||||
|     base_sink(); | ||||
|     explicit base_sink(std::unique_ptr<spdlog::formatter> formatter); | ||||
|     ~base_sink() override = default; | ||||
|  | ||||
|     base_sink(const base_sink &) = delete; | ||||
|     base_sink(base_sink &&) = delete; | ||||
|  | ||||
|     base_sink &operator=(const base_sink &) = delete; | ||||
|     base_sink &operator=(base_sink &&) = delete; | ||||
|  | ||||
|     void log(const details::log_msg &msg) final; | ||||
|     void flush() final; | ||||
|     void set_pattern(const std::string &pattern) final; | ||||
|   | ||||
| @@ -56,7 +56,7 @@ public: | ||||
|     { | ||||
|         if (rotation_hour < 0 || rotation_hour > 23 || rotation_minute < 0 || rotation_minute > 59) | ||||
|         { | ||||
|             SPDLOG_THROW(spdlog_ex("daily_file_sink: Invalid rotation time in ctor")); | ||||
|             throw_spdlog_ex("daily_file_sink: Invalid rotation time in ctor"); | ||||
|         } | ||||
|  | ||||
|         auto now = log_clock::now(); | ||||
| @@ -66,13 +66,13 @@ public: | ||||
|  | ||||
|         if (max_files_ > 0) | ||||
|         { | ||||
|             filenames_q_ = details::circular_q<filename_t>(static_cast<size_t>(max_files_)); | ||||
|             filenames_q_.push_back(std::move(filename)); | ||||
|             init_filenames_q_(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     const filename_t &filename() const | ||||
|     filename_t filename() | ||||
|     { | ||||
|         std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_); | ||||
|         return file_helper_.filename(); | ||||
|     } | ||||
|  | ||||
| @@ -104,6 +104,29 @@ protected: | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void init_filenames_q_() | ||||
|     { | ||||
|         using details::os::path_exists; | ||||
|  | ||||
|         filenames_q_ = details::circular_q<filename_t>(static_cast<size_t>(max_files_)); | ||||
|         std::vector<filename_t> filenames; | ||||
|         auto now = log_clock::now(); | ||||
|         while (filenames.size() < max_files_) | ||||
|         { | ||||
|             auto filename = FileNameCalc::calc_filename(base_filename_, now_tm(now)); | ||||
|             if (!path_exists(filename)) | ||||
|             { | ||||
|                 break; | ||||
|             } | ||||
|             filenames.emplace_back(filename); | ||||
|             now -= std::chrono::hours(24); | ||||
|         } | ||||
|         for (auto iter = filenames.rbegin(); iter != filenames.rend(); ++iter) | ||||
|         { | ||||
|             filenames_q_.push_back(std::move(*iter)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     tm now_tm(log_clock::time_point tp) | ||||
|     { | ||||
|         time_t tnow = log_clock::to_time_t(tp); | ||||
| @@ -141,7 +164,7 @@ private: | ||||
|             if (!ok) | ||||
|             { | ||||
|                 filenames_q_.push_back(std::move(current_file)); | ||||
|                 SPDLOG_THROW(spdlog_ex("Failed removing daily file " + filename_to_str(old_filename), errno)); | ||||
|                 throw_spdlog_ex("Failed removing daily file " + filename_to_str(old_filename), errno); | ||||
|             } | ||||
|         } | ||||
|         filenames_q_.push_back(std::move(current_file)); | ||||
| @@ -167,15 +190,15 @@ using daily_file_sink_st = daily_file_sink<details::null_mutex>; | ||||
| // | ||||
| template<typename Factory = spdlog::synchronous_factory> | ||||
| inline std::shared_ptr<logger> daily_logger_mt( | ||||
|     const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false) | ||||
|     const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0) | ||||
| { | ||||
|     return Factory::template create<sinks::daily_file_sink_mt>(logger_name, filename, hour, minute, truncate); | ||||
|     return Factory::template create<sinks::daily_file_sink_mt>(logger_name, filename, hour, minute, truncate, max_files); | ||||
| } | ||||
|  | ||||
| template<typename Factory = spdlog::synchronous_factory> | ||||
| inline std::shared_ptr<logger> daily_logger_st( | ||||
|     const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false) | ||||
|     const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0) | ||||
| { | ||||
|     return Factory::template create<sinks::daily_file_sink_st>(logger_name, filename, hour, minute, truncate); | ||||
|     return Factory::template create<sinks::daily_file_sink_st>(logger_name, filename, hour, minute, truncate, max_files); | ||||
| } | ||||
| } // namespace spdlog | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| #include "base_sink.h" | ||||
| #include <spdlog/details/log_msg.h> | ||||
| #include <spdlog/details/null_mutex.h> | ||||
| #include <spdlog/details/pattern_formatter.h> | ||||
| #include <spdlog/pattern_formatter.h> | ||||
|  | ||||
| #include <algorithm> | ||||
| #include <memory> | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
| #include <spdlog/details/null_mutex.h> | ||||
| #include <spdlog/sinks/base_sink.h> | ||||
|  | ||||
| #include <spdlog/details/windows_include.h> | ||||
| #include <winbase.h> | ||||
|  | ||||
| #include <mutex> | ||||
|   | ||||
| @@ -54,8 +54,9 @@ SPDLOG_INLINE filename_t rotating_file_sink<Mutex>::calc_filename(const filename | ||||
| } | ||||
|  | ||||
| template<typename Mutex> | ||||
| SPDLOG_INLINE const filename_t &rotating_file_sink<Mutex>::filename() const | ||||
| SPDLOG_INLINE filename_t rotating_file_sink<Mutex>::filename() | ||||
| { | ||||
|     std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_); | ||||
|     return file_helper_.filename(); | ||||
| } | ||||
|  | ||||
| @@ -99,18 +100,17 @@ SPDLOG_INLINE void rotating_file_sink<Mutex>::rotate_() | ||||
|         } | ||||
|         filename_t target = calc_filename(base_filename_, i); | ||||
|  | ||||
|         if (!rename_file(src, target)) | ||||
|         if (!rename_file_(src, target)) | ||||
|         { | ||||
|             // if failed try again after a small delay. | ||||
|             // this is a workaround to a windows issue, where very high rotation | ||||
|             // rates can cause the rename to fail with permission denied (because of antivirus?). | ||||
|             details::os::sleep_for_millis(100); | ||||
|             if (!rename_file(src, target)) | ||||
|             if (!rename_file_(src, target)) | ||||
|             { | ||||
|                 file_helper_.reopen(true); // truncate the log file anyway to prevent it to grow beyond its limit! | ||||
|                 current_size_ = 0; | ||||
|                 SPDLOG_THROW( | ||||
|                     spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno)); | ||||
|                 throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -120,7 +120,7 @@ SPDLOG_INLINE void rotating_file_sink<Mutex>::rotate_() | ||||
| // delete the target if exists, and rename the src file  to target | ||||
| // return true on success, false otherwise. | ||||
| template<typename Mutex> | ||||
| SPDLOG_INLINE bool rotating_file_sink<Mutex>::rename_file(const filename_t &src_filename, const filename_t &target_filename) | ||||
| SPDLOG_INLINE bool rotating_file_sink<Mutex>::rename_file_(const filename_t &src_filename, const filename_t &target_filename) | ||||
| { | ||||
|     // try to delete the target file in case it already exists. | ||||
|     (void)details::os::remove(target_filename); | ||||
|   | ||||
| @@ -24,7 +24,7 @@ class rotating_file_sink final : public base_sink<Mutex> | ||||
| public: | ||||
|     rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false); | ||||
|     static filename_t calc_filename(const filename_t &filename, std::size_t index); | ||||
|     const filename_t &filename() const; | ||||
|     filename_t filename(); | ||||
|  | ||||
| protected: | ||||
|     void sink_it_(const details::log_msg &msg) override; | ||||
| @@ -40,7 +40,7 @@ private: | ||||
|  | ||||
|     // delete the target if exists, and rename the src file  to target | ||||
|     // return true on success, false otherwise. | ||||
|     bool rename_file(const filename_t &src_filename, const filename_t &target_filename); | ||||
|     bool rename_file_(const filename_t &src_filename, const filename_t &target_filename); | ||||
|  | ||||
|     filename_t base_filename_; | ||||
|     std::size_t max_size_; | ||||
| @@ -75,4 +75,4 @@ inline std::shared_ptr<logger> rotating_logger_st( | ||||
|  | ||||
| #ifdef SPDLOG_HEADER_ONLY | ||||
| #include "rotating_file_sink-inl.h" | ||||
| #endif | ||||
| #endif | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| namespace spdlog { | ||||
|  | ||||
| namespace sinks { | ||||
| class sink | ||||
| class SPDLOG_API sink | ||||
| { | ||||
| public: | ||||
|     virtual ~sink() = default; | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| #endif | ||||
|  | ||||
| #include <spdlog/details/console_globals.h> | ||||
| #include <spdlog/details/pattern_formatter.h> | ||||
| #include <spdlog/pattern_formatter.h> | ||||
| #include <memory> | ||||
|  | ||||
| namespace spdlog { | ||||
|   | ||||
| @@ -19,8 +19,12 @@ public: | ||||
|     using mutex_t = typename ConsoleMutex::mutex_t; | ||||
|     explicit stdout_sink_base(FILE *file); | ||||
|     ~stdout_sink_base() override = default; | ||||
|  | ||||
|     stdout_sink_base(const stdout_sink_base &other) = delete; | ||||
|     stdout_sink_base(stdout_sink_base &&other) = delete; | ||||
|  | ||||
|     stdout_sink_base &operator=(const stdout_sink_base &other) = delete; | ||||
|     stdout_sink_base &operator=(stdout_sink_base &&other) = delete; | ||||
|  | ||||
|     void log(const details::log_msg &msg) override; | ||||
|     void flush() override; | ||||
|   | ||||
| @@ -72,7 +72,7 @@ protected: | ||||
|  | ||||
|         if (err) | ||||
|         { | ||||
|             SPDLOG_THROW(spdlog_ex("Failed writing to systemd", errno)); | ||||
|             throw_spdlog_ex("Failed writing to systemd", errno); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										81
									
								
								third_party/spdlog/include/spdlog/sinks/tcp_sink.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								third_party/spdlog/include/spdlog/sinks/tcp_sink.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| // 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/sinks/base_sink.h> | ||||
| #include <spdlog/details/null_mutex.h> | ||||
| #ifdef _WIN32 | ||||
| #include <spdlog/details/tcp_client-windows.h> | ||||
| #else | ||||
| #include <spdlog/details/tcp_client.h> | ||||
| #endif | ||||
|  | ||||
| #include <mutex> | ||||
| #include <string> | ||||
| #include <chrono> | ||||
| #include <functional> | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| // Simple tcp client sink | ||||
| // Connects to remote address and send the formatted log. | ||||
| // Will attempt to reconnect if connection drops. | ||||
| // If more complicated behaviour is needed (i.e get responses), you can inherit it and override the sink_it_ method. | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace sinks { | ||||
|  | ||||
| struct tcp_sink_config | ||||
| { | ||||
|     std::string server_host; | ||||
|     int server_port; | ||||
|     bool lazy_connect = false; // if true connect on first log call instead of on construction | ||||
|  | ||||
|     tcp_sink_config(std::string host, int port) | ||||
|         : server_host{std::move(host)} | ||||
|         , server_port{port} | ||||
|     {} | ||||
| }; | ||||
|  | ||||
| template<typename Mutex> | ||||
| class tcp_sink : public spdlog::sinks::base_sink<Mutex> | ||||
| { | ||||
| public: | ||||
|     // connect to tcp host/port or throw if failed | ||||
|     // host can be hostname or ip address | ||||
|  | ||||
|     explicit tcp_sink(tcp_sink_config sink_config) | ||||
|         : config_{std::move(sink_config)} | ||||
|     { | ||||
|         if (!config_.lazy_connect) | ||||
|         { | ||||
|             this->client_.connect(config_.server_host, config_.server_port); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ~tcp_sink() override = default; | ||||
|  | ||||
| protected: | ||||
|     void sink_it_(const spdlog::details::log_msg &msg) override | ||||
|     { | ||||
|         spdlog::memory_buf_t formatted; | ||||
|         spdlog::sinks::base_sink<Mutex>::formatter_->format(msg, formatted); | ||||
|         if (!client_.is_connected()) | ||||
|         { | ||||
|             client_.connect(config_.server_host, config_.server_port); | ||||
|         } | ||||
|         client_.send(formatted.data(), formatted.size()); | ||||
|     } | ||||
|  | ||||
|     void flush_() override {} | ||||
|     tcp_sink_config config_; | ||||
|     details::tcp_client client_; | ||||
| }; | ||||
|  | ||||
| using tcp_sink_mt = tcp_sink<std::mutex>; | ||||
| using tcp_sink_st = tcp_sink<spdlog::details::null_mutex>; | ||||
|  | ||||
| } // namespace sinks | ||||
| } // namespace spdlog | ||||
							
								
								
									
										266
									
								
								third_party/spdlog/include/spdlog/sinks/win_eventlog_sink.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								third_party/spdlog/include/spdlog/sinks/win_eventlog_sink.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,266 @@ | ||||
| // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. | ||||
| // Distributed under the MIT License (http://opensource.org/licenses/MIT) | ||||
|  | ||||
| // Writing to Windows Event Log requires the registry entries below to be present, with the following modifications: | ||||
| // 1. <log_name>    should be replaced with your log name (e.g. your application name) | ||||
| // 2. <source_name> should be replaced with the specific source name and the key should be duplicated for | ||||
| //                  each source used in the application | ||||
| // | ||||
| // Since typically modifications of this kind require elevation, it's better to do it as a part of setup procedure. | ||||
| // The snippet below uses mscoree.dll as the message file as it exists on most of the Windows systems anyway and | ||||
| // happens to contain the needed resource. | ||||
| // | ||||
| // You can also specify a custom message file if needed. | ||||
| // Please refer to Event Log functions descriptions in MSDN for more details on custom message files. | ||||
|  | ||||
| /*--------------------------------------------------------------------------------------- | ||||
|  | ||||
| Windows Registry Editor Version 5.00 | ||||
|  | ||||
| [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\<log_name>] | ||||
|  | ||||
| [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\<log_name>\<source_name>] | ||||
| "TypesSupported"=dword:00000007 | ||||
| "EventMessageFile"=hex(2):25,00,73,00,79,00,73,00,74,00,65,00,6d,00,72,00,6f,\ | ||||
|   00,6f,00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,\ | ||||
|   5c,00,6d,00,73,00,63,00,6f,00,72,00,65,00,65,00,2e,00,64,00,6c,00,6c,00,00,\ | ||||
|   00 | ||||
|  | ||||
| -----------------------------------------------------------------------------------------*/ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <spdlog/details/null_mutex.h> | ||||
| #include <spdlog/sinks/base_sink.h> | ||||
|  | ||||
| #include <spdlog/details/windows_include.h> | ||||
| #include <winbase.h> | ||||
|  | ||||
| #include <mutex> | ||||
| #include <string> | ||||
| #include <vector> | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace sinks { | ||||
|  | ||||
| namespace win_eventlog { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| /** Windows error */ | ||||
| struct win32_error : public spdlog_ex | ||||
| { | ||||
|     /** Formats an error report line: "user-message: error-code (system message)" */ | ||||
|     static std::string format(std::string const &user_message, DWORD error_code = GetLastError()) | ||||
|     { | ||||
|         std::string system_message; | ||||
|  | ||||
|         LPSTR format_message_result{}; | ||||
|         auto format_message_succeeded = | ||||
|             ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, | ||||
|                 error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&format_message_result, 0, nullptr); | ||||
|  | ||||
|         if (format_message_succeeded && format_message_result) | ||||
|         { | ||||
|             system_message = fmt::format(" ({})", format_message_result); | ||||
|         } | ||||
|  | ||||
|         if (format_message_result) | ||||
|         { | ||||
|             LocalFree((HLOCAL)format_message_result); | ||||
|         } | ||||
|  | ||||
|         return fmt::format("{}: {}{}", user_message, error_code, system_message); | ||||
|     } | ||||
|  | ||||
|     explicit win32_error(std::string const &func_name, DWORD error = GetLastError()) | ||||
|         : spdlog_ex(format(func_name, error)) | ||||
|     {} | ||||
| }; | ||||
|  | ||||
| /** Wrapper for security identifiers (SID) on Windows */ | ||||
| struct sid_t | ||||
| { | ||||
|     std::vector<char> buffer_; | ||||
|  | ||||
| public: | ||||
|     sid_t() {} | ||||
|  | ||||
|     /** creates a wrapped SID copy */ | ||||
|     static sid_t duplicate_sid(PSID psid) | ||||
|     { | ||||
|         if (!::IsValidSid(psid)) | ||||
|         { | ||||
|             throw_spdlog_ex("sid_t::sid_t(): invalid SID received"); | ||||
|         } | ||||
|  | ||||
|         auto const sid_length{::GetLengthSid(psid)}; | ||||
|  | ||||
|         sid_t result; | ||||
|         result.buffer_.resize(sid_length); | ||||
|         if (!::CopySid(sid_length, (PSID)result.as_sid(), psid)) | ||||
|         { | ||||
|             SPDLOG_THROW(win32_error("CopySid")); | ||||
|         } | ||||
|  | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     /** Retrieves pointer to the internal buffer contents as SID* */ | ||||
|     SID *as_sid() const | ||||
|     { | ||||
|         return buffer_.empty() ? nullptr : (SID *)buffer_.data(); | ||||
|     } | ||||
|  | ||||
|     /** Get SID for the current user */ | ||||
|     static sid_t get_current_user_sid() | ||||
|     { | ||||
|         /* create and init RAII holder for process token */ | ||||
|         struct process_token_t | ||||
|         { | ||||
|             HANDLE token_handle_ = INVALID_HANDLE_VALUE; | ||||
|             explicit process_token_t(HANDLE process) | ||||
|             { | ||||
|                 if (!::OpenProcessToken(process, TOKEN_QUERY, &token_handle_)) | ||||
|                 { | ||||
|                     SPDLOG_THROW(win32_error("OpenProcessToken")); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             ~process_token_t() | ||||
|             { | ||||
|                 ::CloseHandle(token_handle_); | ||||
|             } | ||||
|  | ||||
|         } current_process_token(::GetCurrentProcess()); // GetCurrentProcess returns pseudohandle, no leak here! | ||||
|  | ||||
|         // Get the required size, this is expected to fail with ERROR_INSUFFICIENT_BUFFER and return the token size | ||||
|         DWORD tusize = 0; | ||||
|         if (::GetTokenInformation(current_process_token.token_handle_, TokenUser, NULL, 0, &tusize)) | ||||
|         { | ||||
|             SPDLOG_THROW(win32_error("GetTokenInformation should fail")); | ||||
|         } | ||||
|  | ||||
|         // get user token | ||||
|         std::vector<unsigned char> buffer(static_cast<size_t>(tusize)); | ||||
|         if (!::GetTokenInformation(current_process_token.token_handle_, TokenUser, (LPVOID)buffer.data(), tusize, &tusize)) | ||||
|         { | ||||
|             SPDLOG_THROW(win32_error("GetTokenInformation")); | ||||
|         } | ||||
|  | ||||
|         // create a wrapper of the SID data as stored in the user token | ||||
|         return sid_t::duplicate_sid(((TOKEN_USER *)buffer.data())->User.Sid); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| struct eventlog | ||||
| { | ||||
|     static WORD get_event_type(details::log_msg const &msg) | ||||
|     { | ||||
|         switch (msg.level) | ||||
|         { | ||||
|         case level::trace: | ||||
|         case level::debug: | ||||
|             return EVENTLOG_SUCCESS; | ||||
|  | ||||
|         case level::info: | ||||
|             return EVENTLOG_INFORMATION_TYPE; | ||||
|  | ||||
|         case level::warn: | ||||
|             return EVENTLOG_WARNING_TYPE; | ||||
|  | ||||
|         case level::err: | ||||
|         case level::critical: | ||||
|         case level::off: | ||||
|             return EVENTLOG_ERROR_TYPE; | ||||
|  | ||||
|         default: | ||||
|             return EVENTLOG_INFORMATION_TYPE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     static WORD get_event_category(details::log_msg const &msg) | ||||
|     { | ||||
|         return (WORD)msg.level; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace internal | ||||
|  | ||||
| /* | ||||
|  * Windows Event Log sink | ||||
|  */ | ||||
| template<typename Mutex> | ||||
| class win_eventlog_sink : public base_sink<Mutex> | ||||
| { | ||||
| private: | ||||
|     HANDLE hEventLog_{NULL}; | ||||
|     internal::sid_t current_user_sid_; | ||||
|     std::string source_; | ||||
|     WORD event_id_; | ||||
|  | ||||
|     HANDLE event_log_handle() | ||||
|     { | ||||
|         if (!hEventLog_) | ||||
|         { | ||||
|             hEventLog_ = ::RegisterEventSource(nullptr, source_.c_str()); | ||||
|             if (!hEventLog_ || hEventLog_ == (HANDLE)ERROR_ACCESS_DENIED) | ||||
|             { | ||||
|                 SPDLOG_THROW(internal::win32_error("RegisterEventSource")); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return hEventLog_; | ||||
|     } | ||||
|  | ||||
| protected: | ||||
|     void sink_it_(const details::log_msg &msg) override | ||||
|     { | ||||
|         using namespace internal; | ||||
|  | ||||
|         memory_buf_t formatted; | ||||
|         base_sink<Mutex>::formatter_->format(msg, formatted); | ||||
|         formatted.push_back('\0'); | ||||
|         LPCSTR lp_str = static_cast<LPCSTR>(formatted.data()); | ||||
|  | ||||
|         auto succeeded = ::ReportEvent(event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg), event_id_, | ||||
|             current_user_sid_.as_sid(), 1, 0, &lp_str, nullptr); | ||||
|  | ||||
|         if (!succeeded) | ||||
|         { | ||||
|             SPDLOG_THROW(win32_error("ReportEvent")); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void flush_() override {} | ||||
|  | ||||
| public: | ||||
|     win_eventlog_sink(std::string const &source, WORD event_id = 1000 /* according to mscoree.dll */) | ||||
|         : source_(source) | ||||
|         , event_id_(event_id) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             current_user_sid_ = internal::sid_t::get_current_user_sid(); | ||||
|         } | ||||
|         catch (...) | ||||
|         { | ||||
|             // get_current_user_sid() is unlikely to fail and if it does, we can still proceed without | ||||
|             // current_user_sid but in the event log the record will have no user name | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ~win_eventlog_sink() | ||||
|     { | ||||
|         if (hEventLog_) | ||||
|             DeregisterEventSource(hEventLog_); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace win_eventlog | ||||
|  | ||||
| using win_eventlog_sink_mt = win_eventlog::win_eventlog_sink<std::mutex>; | ||||
| using win_eventlog_sink_st = win_eventlog::win_eventlog_sink<details::null_mutex>; | ||||
|  | ||||
| } // namespace sinks | ||||
| } // namespace spdlog | ||||
| @@ -8,7 +8,7 @@ | ||||
| #endif | ||||
|  | ||||
| #include <spdlog/common.h> | ||||
| #include <spdlog/details/pattern_formatter.h> | ||||
| #include <spdlog/pattern_formatter.h> | ||||
|  | ||||
| namespace spdlog { | ||||
| namespace sinks { | ||||
| @@ -52,6 +52,8 @@ template<typename ConsoleMutex> | ||||
| void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::log(const details::log_msg &msg) | ||||
| { | ||||
|     std::lock_guard<mutex_t> lock(mutex_); | ||||
|     msg.color_range_start = 0; | ||||
|     msg.color_range_end = 0; | ||||
|     memory_buf_t formatted; | ||||
|     formatter_->format(msg, formatted); | ||||
|     if (!in_console_) | ||||
| @@ -59,7 +61,6 @@ void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::log(const details::log_msg &msg) | ||||
|         write_to_file_(formatted); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (should_do_colors_ && msg.color_range_end > msg.color_range_start) | ||||
|     { | ||||
|         // before color range | ||||
| @@ -157,7 +158,7 @@ void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::write_to_file_(const memory_buf_ | ||||
|         bool ok = ::WriteFile(out_handle_, formatted.data() + total_written, size - total_written, &bytes_written, nullptr) != 0; | ||||
|         if (!ok || bytes_written == 0) | ||||
|         { | ||||
|             SPDLOG_THROW(spdlog_ex("wincolor_sink: write_to_file_ failed. GetLastError(): " + std::to_string(::GetLastError()))); | ||||
|             throw_spdlog_ex("wincolor_sink: write_to_file_ failed. GetLastError(): " + std::to_string(::GetLastError())); | ||||
|         } | ||||
|         total_written += bytes_written; | ||||
|     } while (total_written < size); | ||||
|   | ||||
| @@ -11,7 +11,9 @@ | ||||
| #include <memory> | ||||
| #include <mutex> | ||||
| #include <string> | ||||
| #include <unordered_map> | ||||
| #include <array> | ||||
|  | ||||
| #include <spdlog/details/windows_include.h> | ||||
| #include <wincon.h> | ||||
|  | ||||
| namespace spdlog { | ||||
| @@ -52,7 +54,7 @@ protected: | ||||
|     bool in_console_; | ||||
|     bool should_do_colors_; | ||||
|     std::unique_ptr<spdlog::formatter> formatter_; | ||||
|     std::unordered_map<level::level_enum, WORD, level::level_hasher> colors_; | ||||
|     std::array<WORD, level::n_levels> colors_; | ||||
|  | ||||
|     // set foreground color and return the orig console attributes (for resetting later) | ||||
|     WORD set_foreground_color_(WORD attribs); | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| #endif | ||||
|  | ||||
| #include <spdlog/common.h> | ||||
| #include <spdlog/details/pattern_formatter.h> | ||||
| #include <spdlog/pattern_formatter.h> | ||||
|  | ||||
| namespace spdlog { | ||||
|  | ||||
|   | ||||
							
								
								
									
										48
									
								
								third_party/spdlog/include/spdlog/spdlog.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										48
									
								
								third_party/spdlog/include/spdlog/spdlog.h
									
									
									
									
										vendored
									
									
								
							| @@ -39,68 +39,66 @@ inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs | ||||
| // Initialize and register a logger, | ||||
| // formatter and flush level will be set according the global settings. | ||||
| // | ||||
| // NOTE: | ||||
| // Use this function when creating loggers manually. | ||||
| // Useful for initializing manually created loggers with the global settings. | ||||
| // | ||||
| // Example: | ||||
| //   auto console_sink = std::make_shared<spdlog::sinks::stdout_sink_mt>(); | ||||
| //   auto console_logger = std::make_shared<spdlog::logger>("console_logger", console_sink); | ||||
| //   spdlog::initialize_logger(console_logger); | ||||
| void initialize_logger(std::shared_ptr<logger> logger); | ||||
| //   auto mylogger = std::make_shared<spdlog::logger>("mylogger", ...); | ||||
| //   spdlog::initialize_logger(mylogger); | ||||
| SPDLOG_API void initialize_logger(std::shared_ptr<logger> logger); | ||||
|  | ||||
| // Return an existing logger or nullptr if a logger with such name doesn't | ||||
| // exist. | ||||
| // example: spdlog::get("my_logger")->info("hello {}", "world"); | ||||
| std::shared_ptr<logger> get(const std::string &name); | ||||
| SPDLOG_API std::shared_ptr<logger> get(const std::string &name); | ||||
|  | ||||
| // Set global formatter. Each sink in each logger will get a clone of this object | ||||
| void set_formatter(std::unique_ptr<spdlog::formatter> formatter); | ||||
| SPDLOG_API void set_formatter(std::unique_ptr<spdlog::formatter> formatter); | ||||
|  | ||||
| // Set global format string. | ||||
| // example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v"); | ||||
| void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local); | ||||
| SPDLOG_API void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local); | ||||
|  | ||||
| // enable global backtrace support | ||||
| void enable_backtrace(size_t n_messages); | ||||
| SPDLOG_API void enable_backtrace(size_t n_messages); | ||||
|  | ||||
| // disable global backtrace support | ||||
| void disable_backtrace(); | ||||
| SPDLOG_API void disable_backtrace(); | ||||
|  | ||||
| // call dump backtrace on default logger | ||||
| void dump_backtrace(); | ||||
| SPDLOG_API void dump_backtrace(); | ||||
|  | ||||
| // Set global logging level | ||||
| void set_level(level::level_enum log_level); | ||||
| SPDLOG_API void set_level(level::level_enum log_level); | ||||
|  | ||||
| // Set global flush level | ||||
| void flush_on(level::level_enum log_level); | ||||
| SPDLOG_API void flush_on(level::level_enum log_level); | ||||
|  | ||||
| // Start/Restart a periodic flusher thread | ||||
| // Warning: Use only if all your loggers are thread safe! | ||||
| void flush_every(std::chrono::seconds interval); | ||||
| SPDLOG_API void flush_every(std::chrono::seconds interval); | ||||
|  | ||||
| // Set global error handler | ||||
| void set_error_handler(void (*handler)(const std::string &msg)); | ||||
| SPDLOG_API void set_error_handler(void (*handler)(const std::string &msg)); | ||||
|  | ||||
| // Register the given logger with the given name | ||||
| void register_logger(std::shared_ptr<logger> logger); | ||||
| SPDLOG_API void register_logger(std::shared_ptr<logger> logger); | ||||
|  | ||||
| // Apply a user defined function on all registered loggers | ||||
| // Example: | ||||
| // spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->flush();}); | ||||
| void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun); | ||||
| SPDLOG_API void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun); | ||||
|  | ||||
| // Drop the reference to the given logger | ||||
| void drop(const std::string &name); | ||||
| SPDLOG_API void drop(const std::string &name); | ||||
|  | ||||
| // Drop all references from the registry | ||||
| void drop_all(); | ||||
| SPDLOG_API void drop_all(); | ||||
|  | ||||
| // stop any running threads started by spdlog and clean registry loggers | ||||
| void shutdown(); | ||||
| SPDLOG_API void shutdown(); | ||||
|  | ||||
| // Automatic registration of loggers when using spdlog::create() or spdlog::create_async | ||||
| void set_automatic_registration(bool automatic_registration); | ||||
| SPDLOG_API void set_automatic_registration(bool automatic_registration); | ||||
|  | ||||
| // API for using default logger (stdout_color_mt), | ||||
| // e.g: spdlog::info("Message {}", 1); | ||||
| @@ -117,11 +115,11 @@ void set_automatic_registration(bool automatic_registration); | ||||
| // set_default_logger() *should not* be used concurrently with the default API. | ||||
| // e.g do not call set_default_logger() from one thread while calling spdlog::info() from another. | ||||
|  | ||||
| std::shared_ptr<spdlog::logger> default_logger(); | ||||
| SPDLOG_API std::shared_ptr<spdlog::logger> default_logger(); | ||||
|  | ||||
| spdlog::logger *default_logger_raw(); | ||||
| SPDLOG_API spdlog::logger *default_logger_raw(); | ||||
|  | ||||
| void set_default_logger(std::shared_ptr<spdlog::logger> default_logger); | ||||
| SPDLOG_API void set_default_logger(std::shared_ptr<spdlog::logger> default_logger); | ||||
|  | ||||
| template<typename... Args> | ||||
| inline void log(source_loc source, level::level_enum lvl, string_view_t fmt, const Args &... args) | ||||
|   | ||||
							
								
								
									
										9
									
								
								third_party/spdlog/include/spdlog/tweakme.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								third_party/spdlog/include/spdlog/tweakme.h
									
									
									
									
										vendored
									
									
								
							| @@ -24,7 +24,7 @@ | ||||
| // This will prevent spdlog from querying the thread id on each log call. | ||||
| // | ||||
| // WARNING: If the log pattern contains thread id (i.e, %t) while this flag is | ||||
| // on, the result is undefined. | ||||
| // on, zero will be logged as thread id. | ||||
| // | ||||
| // #define SPDLOG_NO_THREAD_ID | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -38,13 +38,6 @@ | ||||
| // #define SPDLOG_NO_TLS | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| // Uncomment if logger name logging is not needed. | ||||
| // This will prevent spdlog from copying the logger name on each log call. | ||||
| // | ||||
| // #define SPDLOG_NO_NAME | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| // Uncomment to avoid spdlog's usage of atomic log levels | ||||
| // Use only if your code never modifies a logger's log levels concurrently by | ||||
|   | ||||
							
								
								
									
										2
									
								
								third_party/spdlog/include/spdlog/version.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								third_party/spdlog/include/spdlog/version.h
									
									
									
									
										vendored
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #define SPDLOG_VER_MAJOR 1 | ||||
| #define SPDLOG_VER_MINOR 5 | ||||
| #define SPDLOG_VER_MINOR 6 | ||||
| #define SPDLOG_VER_PATCH 0 | ||||
|  | ||||
| #define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user