mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-21 09:14:47 +08:00
feature: enables basic framework for spdlogs
Related-To: NEO-10510 Signed-off-by: Kulkarni, Ashwin Kumar <ashwin.kumar.kulkarni@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
e0dc228489
commit
8c1f0836ae
1
third_party/spdlog_headers/.version
vendored
Normal file
1
third_party/spdlog_headers/.version
vendored
Normal file
@@ -0,0 +1 @@
|
||||
1.13.0
|
||||
26
third_party/spdlog_headers/LICENSE
vendored
Normal file
26
third_party/spdlog_headers/LICENSE
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Gabi Melman.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
-- NOTE: Third party dependency used by this software --
|
||||
This software depends on the fmt lib (MIT License),
|
||||
and users must comply to its license: https://raw.githubusercontent.com/fmtlib/fmt/master/LICENSE
|
||||
|
||||
3
third_party/spdlog_headers/README.md
vendored
Normal file
3
third_party/spdlog_headers/README.md
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Source locations of interface headers
|
||||
|
||||
https://github.com/gabime/spdlog/tree/v1.x/include/
|
||||
68
third_party/spdlog_headers/spdlog/common-inl.h
vendored
Normal file
68
third_party/spdlog_headers/spdlog/common-inl.h
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
// 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/common.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
namespace spdlog {
|
||||
namespace level {
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
constexpr
|
||||
#endif
|
||||
static string_view_t level_string_views[] SPDLOG_LEVEL_NAMES;
|
||||
|
||||
static const char *short_level_names[] SPDLOG_SHORT_LEVEL_NAMES;
|
||||
|
||||
SPDLOG_INLINE const string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT {
|
||||
return level_string_views[l];
|
||||
}
|
||||
|
||||
SPDLOG_INLINE const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT {
|
||||
return short_level_names[l];
|
||||
}
|
||||
|
||||
SPDLOG_INLINE spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT {
|
||||
auto it = std::find(std::begin(level_string_views), std::end(level_string_views), name);
|
||||
if (it != std::end(level_string_views))
|
||||
return static_cast<level::level_enum>(std::distance(std::begin(level_string_views), it));
|
||||
|
||||
// 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
|
||||
|
||||
SPDLOG_INLINE spdlog_ex::spdlog_ex(std::string msg)
|
||||
: msg_(std::move(msg)) {}
|
||||
|
||||
SPDLOG_INLINE spdlog_ex::spdlog_ex(const std::string &msg, int last_errno) {
|
||||
#ifdef SPDLOG_USE_STD_FORMAT
|
||||
msg_ = std::system_error(std::error_code(last_errno, std::generic_category()), msg).what();
|
||||
#else
|
||||
memory_buf_t outbuf;
|
||||
fmt::format_system_error(outbuf, last_errno, msg.c_str());
|
||||
msg_ = fmt::to_string(outbuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
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
|
||||
411
third_party/spdlog_headers/spdlog/common.h
vendored
Normal file
411
third_party/spdlog_headers/spdlog/common.h
vendored
Normal file
@@ -0,0 +1,411 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/details/null_mutex.h>
|
||||
#include <spdlog/tweakme.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef SPDLOG_USE_STD_FORMAT
|
||||
#include <version>
|
||||
#if __cpp_lib_format >= 202207L
|
||||
#include <format>
|
||||
#else
|
||||
#include <string_view>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SPDLOG_COMPILED_LIB
|
||||
#undef SPDLOG_HEADER_ONLY
|
||||
#if defined(SPDLOG_SHARED_LIB)
|
||||
#if defined(_WIN32)
|
||||
#ifdef spdlog_EXPORTS
|
||||
#define SPDLOG_API __declspec(dllexport)
|
||||
#else // !spdlog_EXPORTS
|
||||
#define SPDLOG_API __declspec(dllimport)
|
||||
#endif
|
||||
#else // !defined(_WIN32)
|
||||
#define SPDLOG_API __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else // !defined(SPDLOG_SHARED_LIB)
|
||||
#define SPDLOG_API
|
||||
#endif
|
||||
#define SPDLOG_INLINE
|
||||
#else // !defined(SPDLOG_COMPILED_LIB)
|
||||
#define SPDLOG_API
|
||||
#define SPDLOG_HEADER_ONLY
|
||||
#define SPDLOG_INLINE inline
|
||||
#endif // #ifdef SPDLOG_COMPILED_LIB
|
||||
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
|
||||
#if !defined(SPDLOG_USE_STD_FORMAT) && \
|
||||
FMT_VERSION >= 80000 // backward compatibility with fmt versions older than 8
|
||||
#define SPDLOG_FMT_RUNTIME(format_string) fmt::runtime(format_string)
|
||||
#define SPDLOG_FMT_STRING(format_string) FMT_STRING(format_string)
|
||||
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
||||
#include <spdlog/fmt/xchar.h>
|
||||
#endif
|
||||
#else
|
||||
#define SPDLOG_FMT_RUNTIME(format_string) format_string
|
||||
#define SPDLOG_FMT_STRING(format_string) format_string
|
||||
#endif
|
||||
|
||||
// visual studio up to 2013 does not support noexcept nor constexpr
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
#define SPDLOG_NOEXCEPT _NOEXCEPT
|
||||
#define SPDLOG_CONSTEXPR
|
||||
#else
|
||||
#define SPDLOG_NOEXCEPT noexcept
|
||||
#define SPDLOG_CONSTEXPR constexpr
|
||||
#endif
|
||||
|
||||
// If building with std::format, can just use constexpr, otherwise if building with fmt
|
||||
// SPDLOG_CONSTEXPR_FUNC needs to be set the same as FMT_CONSTEXPR to avoid situations where
|
||||
// a constexpr function in spdlog could end up calling a non-constexpr function in fmt
|
||||
// depending on the compiler
|
||||
// If fmt determines it can't use constexpr, we should inline the function instead
|
||||
#ifdef SPDLOG_USE_STD_FORMAT
|
||||
#define SPDLOG_CONSTEXPR_FUNC constexpr
|
||||
#else // Being built with fmt
|
||||
#if FMT_USE_CONSTEXPR
|
||||
#define SPDLOG_CONSTEXPR_FUNC FMT_CONSTEXPR
|
||||
#else
|
||||
#define SPDLOG_CONSTEXPR_FUNC inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define SPDLOG_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define SPDLOG_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#define SPDLOG_DEPRECATED
|
||||
#endif
|
||||
|
||||
// disable thread local on msvc 2013
|
||||
#ifndef SPDLOG_NO_TLS
|
||||
#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__cplusplus_winrt)
|
||||
#define SPDLOG_NO_TLS 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SPDLOG_FUNCTION
|
||||
#define SPDLOG_FUNCTION static_cast<const char *>(__FUNCTION__)
|
||||
#endif
|
||||
|
||||
#ifdef SPDLOG_NO_EXCEPTIONS
|
||||
#define SPDLOG_TRY
|
||||
#define SPDLOG_THROW(ex) \
|
||||
do { \
|
||||
printf("spdlog fatal error: %s\n", ex.what()); \
|
||||
std::abort(); \
|
||||
} while (0)
|
||||
#define SPDLOG_CATCH_STD
|
||||
#else
|
||||
#define SPDLOG_TRY try
|
||||
#define SPDLOG_THROW(ex) throw(ex)
|
||||
#define SPDLOG_CATCH_STD \
|
||||
catch (const std::exception &) { \
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
class formatter;
|
||||
|
||||
namespace sinks {
|
||||
class sink;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
|
||||
using filename_t = std::wstring;
|
||||
// allow macro expansion to occur in SPDLOG_FILENAME_T
|
||||
#define SPDLOG_FILENAME_T_INNER(s) L##s
|
||||
#define SPDLOG_FILENAME_T(s) SPDLOG_FILENAME_T_INNER(s)
|
||||
#else
|
||||
using filename_t = std::string;
|
||||
#define SPDLOG_FILENAME_T(s) s
|
||||
#endif
|
||||
|
||||
using log_clock = std::chrono::system_clock;
|
||||
using sink_ptr = std::shared_ptr<sinks::sink>;
|
||||
using sinks_init_list = std::initializer_list<sink_ptr>;
|
||||
using err_handler = std::function<void(const std::string &err_msg)>;
|
||||
#ifdef SPDLOG_USE_STD_FORMAT
|
||||
namespace fmt_lib = std;
|
||||
|
||||
using string_view_t = std::string_view;
|
||||
using memory_buf_t = std::string;
|
||||
|
||||
template <typename... Args>
|
||||
#if __cpp_lib_format >= 202207L
|
||||
using format_string_t = std::format_string<Args...>;
|
||||
#else
|
||||
using format_string_t = std::string_view;
|
||||
#endif
|
||||
|
||||
template <class T, class Char = char>
|
||||
struct is_convertible_to_basic_format_string
|
||||
: std::integral_constant<bool, std::is_convertible<T, std::basic_string_view<Char>>::value> {};
|
||||
|
||||
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
||||
using wstring_view_t = std::wstring_view;
|
||||
using wmemory_buf_t = std::wstring;
|
||||
|
||||
template <typename... Args>
|
||||
#if __cpp_lib_format >= 202207L
|
||||
using wformat_string_t = std::wformat_string<Args...>;
|
||||
#else
|
||||
using wformat_string_t = std::wstring_view;
|
||||
#endif
|
||||
#endif
|
||||
#define SPDLOG_BUF_TO_STRING(x) x
|
||||
#else // use fmt lib instead of std::format
|
||||
namespace fmt_lib = fmt;
|
||||
|
||||
using string_view_t = fmt::basic_string_view<char>;
|
||||
using memory_buf_t = fmt::basic_memory_buffer<char, 250>;
|
||||
|
||||
template <typename... Args>
|
||||
using format_string_t = fmt::format_string<Args...>;
|
||||
|
||||
template <class T>
|
||||
using remove_cvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||
|
||||
template <typename Char>
|
||||
#if FMT_VERSION >= 90101
|
||||
using fmt_runtime_string = fmt::runtime_format_string<Char>;
|
||||
#else
|
||||
using fmt_runtime_string = fmt::basic_runtime<Char>;
|
||||
#endif
|
||||
|
||||
// clang doesn't like SFINAE disabled constructor in std::is_convertible<> so have to repeat the
|
||||
// condition from basic_format_string here, in addition, fmt::basic_runtime<Char> is only
|
||||
// convertible to basic_format_string<Char> but not basic_string_view<Char>
|
||||
template <class T, class Char = char>
|
||||
struct is_convertible_to_basic_format_string
|
||||
: std::integral_constant<bool,
|
||||
std::is_convertible<T, fmt::basic_string_view<Char>>::value ||
|
||||
std::is_same<remove_cvref_t<T>, fmt_runtime_string<Char>>::value> {
|
||||
};
|
||||
|
||||
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
||||
using wstring_view_t = fmt::basic_string_view<wchar_t>;
|
||||
using wmemory_buf_t = fmt::basic_memory_buffer<wchar_t, 250>;
|
||||
|
||||
template <typename... Args>
|
||||
using wformat_string_t = fmt::wformat_string<Args...>;
|
||||
#endif
|
||||
#define SPDLOG_BUF_TO_STRING(x) fmt::to_string(x)
|
||||
#endif
|
||||
|
||||
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
#ifndef _WIN32
|
||||
#error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows
|
||||
#endif // _WIN32
|
||||
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
|
||||
template <class T>
|
||||
struct is_convertible_to_any_format_string
|
||||
: std::integral_constant<bool,
|
||||
is_convertible_to_basic_format_string<T, char>::value ||
|
||||
is_convertible_to_basic_format_string<T, wchar_t>::value> {};
|
||||
|
||||
#if defined(SPDLOG_NO_ATOMIC_LEVELS)
|
||||
using level_t = details::null_atomic_int;
|
||||
#else
|
||||
using level_t = std::atomic<int>;
|
||||
#endif
|
||||
|
||||
#define SPDLOG_LEVEL_TRACE 0
|
||||
#define SPDLOG_LEVEL_DEBUG 1
|
||||
#define SPDLOG_LEVEL_INFO 2
|
||||
#define SPDLOG_LEVEL_WARN 3
|
||||
#define SPDLOG_LEVEL_ERROR 4
|
||||
#define SPDLOG_LEVEL_CRITICAL 5
|
||||
#define SPDLOG_LEVEL_OFF 6
|
||||
|
||||
#if !defined(SPDLOG_ACTIVE_LEVEL)
|
||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
|
||||
#endif
|
||||
|
||||
// Log level enum
|
||||
namespace level {
|
||||
enum level_enum : int {
|
||||
trace = SPDLOG_LEVEL_TRACE,
|
||||
debug = SPDLOG_LEVEL_DEBUG,
|
||||
info = SPDLOG_LEVEL_INFO,
|
||||
warn = SPDLOG_LEVEL_WARN,
|
||||
err = SPDLOG_LEVEL_ERROR,
|
||||
critical = SPDLOG_LEVEL_CRITICAL,
|
||||
off = SPDLOG_LEVEL_OFF,
|
||||
n_levels
|
||||
};
|
||||
|
||||
#define SPDLOG_LEVEL_NAME_TRACE spdlog::string_view_t("trace", 5)
|
||||
#define SPDLOG_LEVEL_NAME_DEBUG spdlog::string_view_t("debug", 5)
|
||||
#define SPDLOG_LEVEL_NAME_INFO spdlog::string_view_t("info", 4)
|
||||
#define SPDLOG_LEVEL_NAME_WARNING spdlog::string_view_t("warning", 7)
|
||||
#define SPDLOG_LEVEL_NAME_ERROR spdlog::string_view_t("error", 5)
|
||||
#define SPDLOG_LEVEL_NAME_CRITICAL spdlog::string_view_t("critical", 8)
|
||||
#define SPDLOG_LEVEL_NAME_OFF spdlog::string_view_t("off", 3)
|
||||
|
||||
#if !defined(SPDLOG_LEVEL_NAMES)
|
||||
#define SPDLOG_LEVEL_NAMES \
|
||||
{ \
|
||||
SPDLOG_LEVEL_NAME_TRACE, SPDLOG_LEVEL_NAME_DEBUG, SPDLOG_LEVEL_NAME_INFO, \
|
||||
SPDLOG_LEVEL_NAME_WARNING, SPDLOG_LEVEL_NAME_ERROR, SPDLOG_LEVEL_NAME_CRITICAL, \
|
||||
SPDLOG_LEVEL_NAME_OFF \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(SPDLOG_SHORT_LEVEL_NAMES)
|
||||
|
||||
#define SPDLOG_SHORT_LEVEL_NAMES \
|
||||
{ "T", "D", "I", "W", "E", "C", "O" }
|
||||
#endif
|
||||
|
||||
SPDLOG_API const 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;
|
||||
|
||||
} // namespace level
|
||||
|
||||
//
|
||||
// Color mode used by sinks with color support.
|
||||
//
|
||||
enum class color_mode { always, automatic, never };
|
||||
|
||||
//
|
||||
// Pattern time - specific time getting to use for pattern_formatter.
|
||||
// local time by default
|
||||
//
|
||||
enum class pattern_time_type {
|
||||
local, // log localtime
|
||||
utc // log utc
|
||||
};
|
||||
|
||||
//
|
||||
// Log exception
|
||||
//
|
||||
class SPDLOG_API spdlog_ex : public std::exception {
|
||||
public:
|
||||
explicit spdlog_ex(std::string msg);
|
||||
spdlog_ex(const std::string &msg, int last_errno);
|
||||
const char *what() const SPDLOG_NOEXCEPT override;
|
||||
|
||||
private:
|
||||
std::string msg_;
|
||||
};
|
||||
|
||||
[[noreturn]] SPDLOG_API void throw_spdlog_ex(const std::string &msg, int last_errno);
|
||||
[[noreturn]] SPDLOG_API void throw_spdlog_ex(std::string msg);
|
||||
|
||||
struct source_loc {
|
||||
SPDLOG_CONSTEXPR source_loc() = default;
|
||||
SPDLOG_CONSTEXPR source_loc(const char *filename_in, int line_in, const char *funcname_in)
|
||||
: filename{filename_in},
|
||||
line{line_in},
|
||||
funcname{funcname_in} {}
|
||||
|
||||
SPDLOG_CONSTEXPR bool empty() const SPDLOG_NOEXCEPT { return line == 0; }
|
||||
const char *filename{nullptr};
|
||||
int line{0};
|
||||
const char *funcname{nullptr};
|
||||
};
|
||||
|
||||
struct file_event_handlers {
|
||||
file_event_handlers()
|
||||
: before_open(nullptr),
|
||||
after_open(nullptr),
|
||||
before_close(nullptr),
|
||||
after_close(nullptr) {}
|
||||
|
||||
std::function<void(const filename_t &filename)> before_open;
|
||||
std::function<void(const filename_t &filename, std::FILE *file_stream)> after_open;
|
||||
std::function<void(const filename_t &filename, std::FILE *file_stream)> before_close;
|
||||
std::function<void(const filename_t &filename)> after_close;
|
||||
};
|
||||
|
||||
namespace details {
|
||||
|
||||
// to_string_view
|
||||
|
||||
SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t to_string_view(const memory_buf_t &buf)
|
||||
SPDLOG_NOEXCEPT {
|
||||
return spdlog::string_view_t{buf.data(), buf.size()};
|
||||
}
|
||||
|
||||
SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t to_string_view(spdlog::string_view_t str)
|
||||
SPDLOG_NOEXCEPT {
|
||||
return str;
|
||||
}
|
||||
|
||||
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
||||
SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t to_string_view(const wmemory_buf_t &buf)
|
||||
SPDLOG_NOEXCEPT {
|
||||
return spdlog::wstring_view_t{buf.data(), buf.size()};
|
||||
}
|
||||
|
||||
SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t to_string_view(spdlog::wstring_view_t str)
|
||||
SPDLOG_NOEXCEPT {
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SPDLOG_USE_STD_FORMAT
|
||||
template <typename T, typename... Args>
|
||||
inline fmt::basic_string_view<T> to_string_view(fmt::basic_format_string<T, Args...> fmt) {
|
||||
return fmt;
|
||||
}
|
||||
#elif __cpp_lib_format >= 202207L
|
||||
template <typename T, typename... Args>
|
||||
SPDLOG_CONSTEXPR_FUNC std::basic_string_view<T> to_string_view(
|
||||
std::basic_format_string<T, Args...> fmt) SPDLOG_NOEXCEPT {
|
||||
return fmt.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
// make_unique support for pre c++14
|
||||
#if __cplusplus >= 201402L // C++14 and beyond
|
||||
using std::enable_if_t;
|
||||
using std::make_unique;
|
||||
#else
|
||||
template <bool B, class T = void>
|
||||
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||
|
||||
template <typename T, typename... Args>
|
||||
std::unique_ptr<T> make_unique(Args &&...args) {
|
||||
static_assert(!std::is_array<T>::value, "arrays not supported");
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
#endif
|
||||
|
||||
// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
|
||||
template <typename T, typename U, enable_if_t<!std::is_same<T, U>::value, int> = 0>
|
||||
constexpr T conditional_static_cast(U value) {
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
template <typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
|
||||
constexpr T conditional_static_cast(U value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "common-inl.h"
|
||||
#endif
|
||||
63
third_party/spdlog_headers/spdlog/details/backtracer-inl.h
vendored
Normal file
63
third_party/spdlog_headers/spdlog/details/backtracer-inl.h
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SPDLOG_HEADER_ONLY
|
||||
#include <spdlog/details/backtracer.h>
|
||||
#endif
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
SPDLOG_INLINE backtracer::backtracer(const backtracer &other) {
|
||||
std::lock_guard<std::mutex> lock(other.mutex_);
|
||||
enabled_ = other.enabled();
|
||||
messages_ = other.messages_;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE backtracer::backtracer(backtracer &&other) SPDLOG_NOEXCEPT {
|
||||
std::lock_guard<std::mutex> lock(other.mutex_);
|
||||
enabled_ = other.enabled();
|
||||
messages_ = std::move(other.messages_);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE backtracer &backtracer::operator=(backtracer other) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
enabled_ = other.enabled();
|
||||
messages_ = std::move(other.messages_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void backtracer::enable(size_t size) {
|
||||
std::lock_guard<std::mutex> lock{mutex_};
|
||||
enabled_.store(true, std::memory_order_relaxed);
|
||||
messages_ = circular_q<log_msg_buffer>{size};
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void backtracer::disable() {
|
||||
std::lock_guard<std::mutex> lock{mutex_};
|
||||
enabled_.store(false, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE bool backtracer::enabled() const { return enabled_.load(std::memory_order_relaxed); }
|
||||
|
||||
SPDLOG_INLINE void backtracer::push_back(const log_msg &msg) {
|
||||
std::lock_guard<std::mutex> lock{mutex_};
|
||||
messages_.push_back(log_msg_buffer{msg});
|
||||
}
|
||||
|
||||
SPDLOG_INLINE bool backtracer::empty() const {
|
||||
std::lock_guard<std::mutex> lock{mutex_};
|
||||
return messages_.empty();
|
||||
}
|
||||
|
||||
// pop all items in the q and apply the given fun on each of them.
|
||||
SPDLOG_INLINE void backtracer::foreach_pop(std::function<void(const details::log_msg &)> fun) {
|
||||
std::lock_guard<std::mutex> lock{mutex_};
|
||||
while (!messages_.empty()) {
|
||||
auto &front_msg = messages_.front();
|
||||
fun(front_msg);
|
||||
messages_.pop_front();
|
||||
}
|
||||
}
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
45
third_party/spdlog_headers/spdlog/details/backtracer.h
vendored
Normal file
45
third_party/spdlog_headers/spdlog/details/backtracer.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/details/circular_q.h>
|
||||
#include <spdlog/details/log_msg_buffer.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
// Store log messages in circular buffer.
|
||||
// Useful for storing debug data in case of error/warning happens.
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
class SPDLOG_API backtracer {
|
||||
mutable std::mutex mutex_;
|
||||
std::atomic<bool> enabled_{false};
|
||||
circular_q<log_msg_buffer> messages_;
|
||||
|
||||
public:
|
||||
backtracer() = default;
|
||||
backtracer(const backtracer &other);
|
||||
|
||||
backtracer(backtracer &&other) SPDLOG_NOEXCEPT;
|
||||
backtracer &operator=(backtracer other);
|
||||
|
||||
void enable(size_t size);
|
||||
void disable();
|
||||
bool enabled() const;
|
||||
void push_back(const log_msg &msg);
|
||||
bool empty() const;
|
||||
|
||||
// pop all items in the q and apply the given fun on each of them.
|
||||
void foreach_pop(std::function<void(const details::log_msg &)> fun);
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "backtracer-inl.h"
|
||||
#endif
|
||||
113
third_party/spdlog_headers/spdlog/details/circular_q.h
vendored
Normal file
113
third_party/spdlog_headers/spdlog/details/circular_q.h
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
// circular q view of std::vector.
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
template <typename T>
|
||||
class circular_q {
|
||||
size_t max_items_ = 0;
|
||||
typename std::vector<T>::size_type head_ = 0;
|
||||
typename std::vector<T>::size_type tail_ = 0;
|
||||
size_t overrun_counter_ = 0;
|
||||
std::vector<T> v_;
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
// empty ctor - create a disabled queue with no elements allocated at all
|
||||
circular_q() = default;
|
||||
|
||||
explicit circular_q(size_t max_items)
|
||||
: max_items_(max_items + 1) // one item is reserved as marker for full q
|
||||
,
|
||||
v_(max_items_) {}
|
||||
|
||||
circular_q(const circular_q &) = default;
|
||||
circular_q &operator=(const circular_q &) = default;
|
||||
|
||||
// move cannot be default,
|
||||
// since we need to reset head_, tail_, etc to zero in the moved object
|
||||
circular_q(circular_q &&other) SPDLOG_NOEXCEPT { copy_moveable(std::move(other)); }
|
||||
|
||||
circular_q &operator=(circular_q &&other) SPDLOG_NOEXCEPT {
|
||||
copy_moveable(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// push back, overrun (oldest) item if no room left
|
||||
void push_back(T &&item) {
|
||||
if (max_items_ > 0) {
|
||||
v_[tail_] = std::move(item);
|
||||
tail_ = (tail_ + 1) % max_items_;
|
||||
|
||||
if (tail_ == head_) // overrun last item if full
|
||||
{
|
||||
head_ = (head_ + 1) % max_items_;
|
||||
++overrun_counter_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return reference to the front item.
|
||||
// If there are no elements in the container, the behavior is undefined.
|
||||
const T &front() const { return v_[head_]; }
|
||||
|
||||
T &front() { return v_[head_]; }
|
||||
|
||||
// Return number of elements actually stored
|
||||
size_t size() const {
|
||||
if (tail_ >= head_) {
|
||||
return tail_ - head_;
|
||||
} else {
|
||||
return max_items_ - (head_ - tail_);
|
||||
}
|
||||
}
|
||||
|
||||
// Return const reference to item by index.
|
||||
// If index is out of range 0…size()-1, the behavior is undefined.
|
||||
const T &at(size_t i) const {
|
||||
assert(i < size());
|
||||
return v_[(head_ + i) % max_items_];
|
||||
}
|
||||
|
||||
// Pop item from front.
|
||||
// If there are no elements in the container, the behavior is undefined.
|
||||
void pop_front() { head_ = (head_ + 1) % max_items_; }
|
||||
|
||||
bool empty() const { return tail_ == head_; }
|
||||
|
||||
bool full() const {
|
||||
// head is ahead of the tail by 1
|
||||
if (max_items_ > 0) {
|
||||
return ((tail_ + 1) % max_items_) == head_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t overrun_counter() const { return overrun_counter_; }
|
||||
|
||||
void reset_overrun_counter() { overrun_counter_ = 0; }
|
||||
|
||||
private:
|
||||
// copy from other&& and reset it to disabled state
|
||||
void copy_moveable(circular_q &&other) SPDLOG_NOEXCEPT {
|
||||
max_items_ = other.max_items_;
|
||||
head_ = other.head_;
|
||||
tail_ = other.tail_;
|
||||
overrun_counter_ = other.overrun_counter_;
|
||||
v_ = std::move(other.v_);
|
||||
|
||||
// put &&other in disabled, but valid state
|
||||
other.max_items_ = 0;
|
||||
other.head_ = other.tail_ = 0;
|
||||
other.overrun_counter_ = 0;
|
||||
}
|
||||
};
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
28
third_party/spdlog_headers/spdlog/details/console_globals.h
vendored
Normal file
28
third_party/spdlog_headers/spdlog/details/console_globals.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 <mutex>
|
||||
#include <spdlog/details/null_mutex.h>
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
struct console_mutex {
|
||||
using mutex_t = std::mutex;
|
||||
static mutex_t &mutex() {
|
||||
static mutex_t s_mutex;
|
||||
return s_mutex;
|
||||
}
|
||||
};
|
||||
|
||||
struct console_nullmutex {
|
||||
using mutex_t = null_mutex;
|
||||
static mutex_t &mutex() {
|
||||
static mutex_t s_mutex;
|
||||
return s_mutex;
|
||||
}
|
||||
};
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
152
third_party/spdlog_headers/spdlog/details/file_helper-inl.h
vendored
Normal file
152
third_party/spdlog_headers/spdlog/details/file_helper-inl.h
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SPDLOG_HEADER_ONLY
|
||||
#include <spdlog/details/file_helper.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/details/os.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
SPDLOG_INLINE file_helper::file_helper(const file_event_handlers &event_handlers)
|
||||
: event_handlers_(event_handlers) {}
|
||||
|
||||
SPDLOG_INLINE file_helper::~file_helper() { close(); }
|
||||
|
||||
SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate) {
|
||||
close();
|
||||
filename_ = fname;
|
||||
|
||||
auto *mode = SPDLOG_FILENAME_T("ab");
|
||||
auto *trunc_mode = SPDLOG_FILENAME_T("wb");
|
||||
|
||||
if (event_handlers_.before_open) {
|
||||
event_handlers_.before_open(filename_);
|
||||
}
|
||||
for (int tries = 0; tries < open_tries_; ++tries) {
|
||||
// create containing folder if not exists already.
|
||||
os::create_dir(os::dir_name(fname));
|
||||
if (truncate) {
|
||||
// Truncate by opening-and-closing a tmp file in "wb" mode, always
|
||||
// opening the actual log-we-write-to in "ab" mode, since that
|
||||
// interacts more politely with eternal processes that might
|
||||
// rotate/truncate the file underneath us.
|
||||
std::FILE *tmp;
|
||||
if (os::fopen_s(&tmp, fname, trunc_mode)) {
|
||||
continue;
|
||||
}
|
||||
std::fclose(tmp);
|
||||
}
|
||||
if (!os::fopen_s(&fd_, fname, mode)) {
|
||||
if (event_handlers_.after_open) {
|
||||
event_handlers_.after_open(filename_, fd_);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
details::os::sleep_for_millis(open_interval_);
|
||||
}
|
||||
|
||||
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()) {
|
||||
throw_spdlog_ex("Failed re opening file - was not opened before");
|
||||
}
|
||||
this->open(filename_, truncate);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void file_helper::flush() {
|
||||
if (std::fflush(fd_) != 0) {
|
||||
throw_spdlog_ex("Failed flush to file " + os::filename_to_str(filename_), errno);
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void file_helper::sync() {
|
||||
if (!os::fsync(fd_)) {
|
||||
throw_spdlog_ex("Failed to fsync file " + os::filename_to_str(filename_), errno);
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void file_helper::close() {
|
||||
if (fd_ != nullptr) {
|
||||
if (event_handlers_.before_close) {
|
||||
event_handlers_.before_close(filename_, fd_);
|
||||
}
|
||||
|
||||
std::fclose(fd_);
|
||||
fd_ = nullptr;
|
||||
|
||||
if (event_handlers_.after_close) {
|
||||
event_handlers_.after_close(filename_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void file_helper::write(const memory_buf_t &buf) {
|
||||
if(fd_ == nullptr) return;
|
||||
size_t msg_size = buf.size();
|
||||
auto data = buf.data();
|
||||
if (std::fwrite(data, 1, msg_size, fd_) != msg_size) {
|
||||
throw_spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno);
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE size_t file_helper::size() const {
|
||||
if (fd_ == nullptr) {
|
||||
throw_spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_));
|
||||
}
|
||||
return os::filesize(fd_);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE const filename_t &file_helper::filename() const { return filename_; }
|
||||
|
||||
//
|
||||
// return file path and its extension:
|
||||
//
|
||||
// "mylog.txt" => ("mylog", ".txt")
|
||||
// "mylog" => ("mylog", "")
|
||||
// "mylog." => ("mylog.", "")
|
||||
// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
|
||||
//
|
||||
// the starting dot in filenames is ignored (hidden files):
|
||||
//
|
||||
// ".mylog" => (".mylog". "")
|
||||
// "my_folder/.mylog" => ("my_folder/.mylog", "")
|
||||
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
|
||||
SPDLOG_INLINE std::tuple<filename_t, filename_t> file_helper::split_by_extension(
|
||||
const filename_t &fname) {
|
||||
auto ext_index = fname.rfind('.');
|
||||
|
||||
// no valid extension found - return whole path and empty string as
|
||||
// extension
|
||||
if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1) {
|
||||
return std::make_tuple(fname, filename_t());
|
||||
}
|
||||
|
||||
// treat cases like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
|
||||
auto folder_index = fname.find_last_of(details::os::folder_seps_filename);
|
||||
if (folder_index != filename_t::npos && folder_index >= ext_index - 1) {
|
||||
return std::make_tuple(fname, filename_t());
|
||||
}
|
||||
|
||||
// finally - return a valid base and extension tuple
|
||||
return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
61
third_party/spdlog_headers/spdlog/details/file_helper.h
vendored
Normal file
61
third_party/spdlog_headers/spdlog/details/file_helper.h
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// 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 <tuple>
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
// Helper class for file sinks.
|
||||
// When failing to open a file, retry several times(5) with a delay interval(10 ms).
|
||||
// Throw spdlog_ex exception on errors.
|
||||
|
||||
class SPDLOG_API file_helper {
|
||||
public:
|
||||
file_helper() = default;
|
||||
explicit file_helper(const file_event_handlers &event_handlers);
|
||||
|
||||
file_helper(const file_helper &) = delete;
|
||||
file_helper &operator=(const file_helper &) = delete;
|
||||
~file_helper();
|
||||
|
||||
void open(const filename_t &fname, bool truncate = false);
|
||||
void reopen(bool truncate);
|
||||
void flush();
|
||||
void sync();
|
||||
void close();
|
||||
void write(const memory_buf_t &buf);
|
||||
size_t size() const;
|
||||
const filename_t &filename() const;
|
||||
|
||||
//
|
||||
// return file path and its extension:
|
||||
//
|
||||
// "mylog.txt" => ("mylog", ".txt")
|
||||
// "mylog" => ("mylog", "")
|
||||
// "mylog." => ("mylog.", "")
|
||||
// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
|
||||
//
|
||||
// the starting dot in filenames is ignored (hidden files):
|
||||
//
|
||||
// ".mylog" => (".mylog". "")
|
||||
// "my_folder/.mylog" => ("my_folder/.mylog", "")
|
||||
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
|
||||
static std::tuple<filename_t, filename_t> split_by_extension(const filename_t &fname);
|
||||
|
||||
private:
|
||||
const int open_tries_ = 5;
|
||||
const unsigned int open_interval_ = 10;
|
||||
std::FILE *fd_{nullptr};
|
||||
filename_t filename_;
|
||||
file_event_handlers event_handlers_;
|
||||
};
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "file_helper-inl.h"
|
||||
#endif
|
||||
141
third_party/spdlog_headers/spdlog/details/fmt_helper.h
vendored
Normal file
141
third_party/spdlog_headers/spdlog/details/fmt_helper.h
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <iterator>
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef SPDLOG_USE_STD_FORMAT
|
||||
#include <charconv>
|
||||
#include <limits>
|
||||
#endif
|
||||
|
||||
// Some fmt helpers to efficiently format and pad ints and strings
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
namespace fmt_helper {
|
||||
|
||||
inline void append_string_view(spdlog::string_view_t view, memory_buf_t &dest) {
|
||||
auto *buf_ptr = view.data();
|
||||
dest.append(buf_ptr, buf_ptr + view.size());
|
||||
}
|
||||
|
||||
#ifdef SPDLOG_USE_STD_FORMAT
|
||||
template <typename T>
|
||||
inline void append_int(T n, memory_buf_t &dest) {
|
||||
// Buffer should be large enough to hold all digits (digits10 + 1) and a sign
|
||||
SPDLOG_CONSTEXPR const auto BUF_SIZE = std::numeric_limits<T>::digits10 + 2;
|
||||
char buf[BUF_SIZE];
|
||||
|
||||
auto [ptr, ec] = std::to_chars(buf, buf + BUF_SIZE, n, 10);
|
||||
if (ec == std::errc()) {
|
||||
dest.append(buf, ptr);
|
||||
} else {
|
||||
throw_spdlog_ex("Failed to format int", static_cast<int>(ec));
|
||||
}
|
||||
}
|
||||
#else
|
||||
template <typename T>
|
||||
inline void append_int(T n, memory_buf_t &dest) {
|
||||
fmt::format_int i(n);
|
||||
dest.append(i.data(), i.data() + i.size());
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
SPDLOG_CONSTEXPR_FUNC unsigned int count_digits_fallback(T n) {
|
||||
// taken from fmt: https://github.com/fmtlib/fmt/blob/8.0.1/include/fmt/format.h#L899-L912
|
||||
unsigned int count = 1;
|
||||
for (;;) {
|
||||
// Integer division is slow so do it for a group of four digits instead
|
||||
// of for every digit. The idea comes from the talk by Alexandrescu
|
||||
// "Three Optimization Tips for C++". See speed-test for a comparison.
|
||||
if (n < 10) return count;
|
||||
if (n < 100) return count + 1;
|
||||
if (n < 1000) return count + 2;
|
||||
if (n < 10000) return count + 3;
|
||||
n /= 10000u;
|
||||
count += 4;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline unsigned int count_digits(T n) {
|
||||
using count_type =
|
||||
typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type;
|
||||
#ifdef SPDLOG_USE_STD_FORMAT
|
||||
return count_digits_fallback(static_cast<count_type>(n));
|
||||
#else
|
||||
return static_cast<unsigned int>(fmt::
|
||||
// fmt 7.0.0 renamed the internal namespace to detail.
|
||||
// See: https://github.com/fmtlib/fmt/issues/1538
|
||||
#if FMT_VERSION < 70000
|
||||
internal
|
||||
#else
|
||||
detail
|
||||
#endif
|
||||
::count_digits(static_cast<count_type>(n)));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void pad2(int n, memory_buf_t &dest) {
|
||||
if (n >= 0 && n < 100) // 0-99
|
||||
{
|
||||
dest.push_back(static_cast<char>('0' + n / 10));
|
||||
dest.push_back(static_cast<char>('0' + n % 10));
|
||||
} else // unlikely, but just in case, let fmt deal with it
|
||||
{
|
||||
fmt_lib::format_to(std::back_inserter(dest), SPDLOG_FMT_STRING("{:02}"), n);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
for (auto digits = count_digits(n); digits < width; digits++) {
|
||||
dest.push_back('0');
|
||||
}
|
||||
append_int(n, dest);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void pad3(T n, memory_buf_t &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>
|
||||
inline void pad6(T n, memory_buf_t &dest) {
|
||||
pad_uint(n, 6, dest);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void pad9(T n, memory_buf_t &dest) {
|
||||
pad_uint(n, 9, dest);
|
||||
}
|
||||
|
||||
// return fraction of a second of the given time_point.
|
||||
// e.g.
|
||||
// fraction<std::milliseconds>(tp) -> will return the millis part of the second
|
||||
template <typename ToDuration>
|
||||
inline ToDuration time_fraction(log_clock::time_point tp) {
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::seconds;
|
||||
auto duration = tp.time_since_epoch();
|
||||
auto secs = duration_cast<seconds>(duration);
|
||||
return duration_cast<ToDuration>(duration) - duration_cast<ToDuration>(secs);
|
||||
}
|
||||
|
||||
} // namespace fmt_helper
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
44
third_party/spdlog_headers/spdlog/details/log_msg-inl.h
vendored
Normal file
44
third_party/spdlog_headers/spdlog/details/log_msg-inl.h
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SPDLOG_HEADER_ONLY
|
||||
#include <spdlog/details/log_msg.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/details/os.h>
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
SPDLOG_INLINE log_msg::log_msg(spdlog::log_clock::time_point log_time,
|
||||
spdlog::source_loc loc,
|
||||
string_view_t a_logger_name,
|
||||
spdlog::level::level_enum lvl,
|
||||
spdlog::string_view_t msg)
|
||||
: logger_name(a_logger_name),
|
||||
level(lvl),
|
||||
time(log_time)
|
||||
#ifndef SPDLOG_NO_THREAD_ID
|
||||
,
|
||||
thread_id(os::thread_id())
|
||||
#endif
|
||||
,
|
||||
source(loc),
|
||||
payload(msg) {
|
||||
}
|
||||
|
||||
SPDLOG_INLINE log_msg::log_msg(spdlog::source_loc loc,
|
||||
string_view_t a_logger_name,
|
||||
spdlog::level::level_enum lvl,
|
||||
spdlog::string_view_t msg)
|
||||
: log_msg(os::now(), loc, a_logger_name, lvl, msg) {}
|
||||
|
||||
SPDLOG_INLINE log_msg::log_msg(string_view_t a_logger_name,
|
||||
spdlog::level::level_enum lvl,
|
||||
spdlog::string_view_t msg)
|
||||
: log_msg(os::now(), source_loc{}, a_logger_name, lvl, msg) {}
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
40
third_party/spdlog_headers/spdlog/details/log_msg.h
vendored
Normal file
40
third_party/spdlog_headers/spdlog/details/log_msg.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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>
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
struct SPDLOG_API log_msg {
|
||||
log_msg() = default;
|
||||
log_msg(log_clock::time_point log_time,
|
||||
source_loc loc,
|
||||
string_view_t logger_name,
|
||||
level::level_enum lvl,
|
||||
string_view_t msg);
|
||||
log_msg(source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg);
|
||||
log_msg(string_view_t logger_name, level::level_enum lvl, string_view_t msg);
|
||||
log_msg(const log_msg &other) = default;
|
||||
log_msg &operator=(const log_msg &other) = default;
|
||||
|
||||
string_view_t logger_name;
|
||||
level::level_enum level{level::off};
|
||||
log_clock::time_point time;
|
||||
size_t thread_id{0};
|
||||
|
||||
// wrapping the formatted text with color (updated by pattern_formatter).
|
||||
mutable size_t color_range_start{0};
|
||||
mutable size_t color_range_end{0};
|
||||
|
||||
source_loc source;
|
||||
string_view_t payload;
|
||||
};
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "log_msg-inl.h"
|
||||
#endif
|
||||
54
third_party/spdlog_headers/spdlog/details/log_msg_buffer-inl.h
vendored
Normal file
54
third_party/spdlog_headers/spdlog/details/log_msg_buffer-inl.h
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SPDLOG_HEADER_ONLY
|
||||
#include <spdlog/details/log_msg_buffer.h>
|
||||
#endif
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
SPDLOG_INLINE log_msg_buffer::log_msg_buffer(const log_msg &orig_msg)
|
||||
: log_msg{orig_msg} {
|
||||
buffer.append(logger_name.begin(), logger_name.end());
|
||||
buffer.append(payload.begin(), payload.end());
|
||||
update_string_views();
|
||||
}
|
||||
|
||||
SPDLOG_INLINE log_msg_buffer::log_msg_buffer(const log_msg_buffer &other)
|
||||
: log_msg{other} {
|
||||
buffer.append(logger_name.begin(), logger_name.end());
|
||||
buffer.append(payload.begin(), payload.end());
|
||||
update_string_views();
|
||||
}
|
||||
|
||||
SPDLOG_INLINE log_msg_buffer::log_msg_buffer(log_msg_buffer &&other) SPDLOG_NOEXCEPT
|
||||
: log_msg{other},
|
||||
buffer{std::move(other.buffer)} {
|
||||
update_string_views();
|
||||
}
|
||||
|
||||
SPDLOG_INLINE log_msg_buffer &log_msg_buffer::operator=(const log_msg_buffer &other) {
|
||||
log_msg::operator=(other);
|
||||
buffer.clear();
|
||||
buffer.append(other.buffer.data(), other.buffer.data() + other.buffer.size());
|
||||
update_string_views();
|
||||
return *this;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE log_msg_buffer &log_msg_buffer::operator=(log_msg_buffer &&other) SPDLOG_NOEXCEPT {
|
||||
log_msg::operator=(other);
|
||||
buffer = std::move(other.buffer);
|
||||
update_string_views();
|
||||
return *this;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void log_msg_buffer::update_string_views() {
|
||||
logger_name = string_view_t{buffer.data(), logger_name.size()};
|
||||
payload = string_view_t{buffer.data() + logger_name.size(), payload.size()};
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
32
third_party/spdlog_headers/spdlog/details/log_msg_buffer.h
vendored
Normal file
32
third_party/spdlog_headers/spdlog/details/log_msg_buffer.h
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/details/log_msg.h>
|
||||
|
||||
namespace spdlog {
|
||||
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 SPDLOG_API log_msg_buffer : public log_msg {
|
||||
memory_buf_t buffer;
|
||||
void update_string_views();
|
||||
|
||||
public:
|
||||
log_msg_buffer() = default;
|
||||
explicit log_msg_buffer(const log_msg &orig_msg);
|
||||
log_msg_buffer(const log_msg_buffer &other);
|
||||
log_msg_buffer(log_msg_buffer &&other) SPDLOG_NOEXCEPT;
|
||||
log_msg_buffer &operator=(const log_msg_buffer &other);
|
||||
log_msg_buffer &operator=(log_msg_buffer &&other) SPDLOG_NOEXCEPT;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "log_msg_buffer-inl.h"
|
||||
#endif
|
||||
35
third_party/spdlog_headers/spdlog/details/null_mutex.h
vendored
Normal file
35
third_party/spdlog_headers/spdlog/details/null_mutex.h
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <utility>
|
||||
// null, no cost dummy "mutex" and dummy "atomic" int
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
struct null_mutex {
|
||||
void lock() const {}
|
||||
void unlock() const {}
|
||||
};
|
||||
|
||||
struct null_atomic_int {
|
||||
int value;
|
||||
null_atomic_int() = default;
|
||||
|
||||
explicit null_atomic_int(int new_value)
|
||||
: value(new_value) {}
|
||||
|
||||
int load(std::memory_order = std::memory_order_relaxed) const { return value; }
|
||||
|
||||
void store(int new_value, std::memory_order = std::memory_order_relaxed) { value = new_value; }
|
||||
|
||||
int exchange(int new_value, std::memory_order = std::memory_order_relaxed) {
|
||||
std::swap(new_value, value);
|
||||
return new_value; // return value before the call
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
585
third_party/spdlog_headers/spdlog/details/os-inl.h
vendored
Normal file
585
third_party/spdlog_headers/spdlog/details/os-inl.h
vendored
Normal file
@@ -0,0 +1,585 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SPDLOG_HEADER_ONLY
|
||||
#include <spdlog/details/os.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/common.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <thread>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <spdlog/details/windows_include.h>
|
||||
#include <fileapi.h> // for FlushFileBuffers
|
||||
#include <io.h> // for _get_osfhandle, _isatty, _fileno
|
||||
#include <process.h> // for _get_pid
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <share.h>
|
||||
#endif
|
||||
|
||||
#if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#endif
|
||||
|
||||
#include <direct.h> // for _mkdir/_wmkdir
|
||||
|
||||
#else // unix
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/syscall.h> //Use gettid() syscall under linux to get thread id
|
||||
|
||||
#elif defined(_AIX)
|
||||
#include <pthread.h> // for pthread_getthrds_np
|
||||
|
||||
#elif defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
#include <pthread_np.h> // for pthread_getthreadid_np
|
||||
|
||||
#elif defined(__NetBSD__)
|
||||
#include <lwp.h> // for _lwp_self
|
||||
|
||||
#elif defined(__sun)
|
||||
#include <thread.h> // for thr_self
|
||||
#endif
|
||||
|
||||
#endif // unix
|
||||
|
||||
#if defined __APPLE__
|
||||
#include <AvailabilityMacros.h>
|
||||
#endif
|
||||
|
||||
#ifndef __has_feature // Clang - feature checking macros.
|
||||
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
|
||||
#endif
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
namespace os {
|
||||
|
||||
SPDLOG_INLINE spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT {
|
||||
#if defined __linux__ && defined SPDLOG_CLOCK_COARSE
|
||||
timespec ts;
|
||||
::clock_gettime(CLOCK_REALTIME_COARSE, &ts);
|
||||
return std::chrono::time_point<log_clock, typename log_clock::duration>(
|
||||
std::chrono::duration_cast<typename log_clock::duration>(
|
||||
std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec)));
|
||||
|
||||
#else
|
||||
return log_clock::now();
|
||||
#endif
|
||||
}
|
||||
SPDLOG_INLINE std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT {
|
||||
#ifdef _WIN32
|
||||
std::tm tm;
|
||||
::localtime_s(&tm, &time_tt);
|
||||
#else
|
||||
std::tm tm;
|
||||
::localtime_r(&time_tt, &tm);
|
||||
#endif
|
||||
return tm;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE std::tm localtime() SPDLOG_NOEXCEPT {
|
||||
std::time_t now_t = ::time(nullptr);
|
||||
return localtime(now_t);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT {
|
||||
#ifdef _WIN32
|
||||
std::tm tm;
|
||||
::gmtime_s(&tm, &time_tt);
|
||||
#else
|
||||
std::tm tm;
|
||||
::gmtime_r(&time_tt, &tm);
|
||||
#endif
|
||||
return tm;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE std::tm gmtime() SPDLOG_NOEXCEPT {
|
||||
std::time_t now_t = ::time(nullptr);
|
||||
return gmtime(now_t);
|
||||
}
|
||||
|
||||
// fopen_s on non windows for writing
|
||||
SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode) {
|
||||
#ifdef _WIN32
|
||||
#ifdef SPDLOG_WCHAR_FILENAMES
|
||||
*fp = ::_wfsopen((filename.c_str()), mode.c_str(), _SH_DENYNO);
|
||||
#else
|
||||
*fp = ::_fsopen((filename.c_str()), mode.c_str(), _SH_DENYNO);
|
||||
#endif
|
||||
#if defined(SPDLOG_PREVENT_CHILD_FD)
|
||||
if (*fp != nullptr) {
|
||||
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 true;
|
||||
}
|
||||
*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;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE int remove(const filename_t &filename) SPDLOG_NOEXCEPT {
|
||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
|
||||
return ::_wremove(filename.c_str());
|
||||
#else
|
||||
return std::remove(filename.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
SPDLOG_INLINE int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT {
|
||||
return path_exists(filename) ? remove(filename) : 0;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT {
|
||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
|
||||
return ::_wrename(filename1.c_str(), filename2.c_str());
|
||||
#else
|
||||
return std::rename(filename1.c_str(), filename2.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return true if path exists (file or directory)
|
||||
SPDLOG_INLINE bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT {
|
||||
#ifdef _WIN32
|
||||
struct _stat buffer;
|
||||
#ifdef SPDLOG_WCHAR_FILENAMES
|
||||
return (::_wstat(filename.c_str(), &buffer) == 0);
|
||||
#else
|
||||
return (::_stat(filename.c_str(), &buffer) == 0);
|
||||
#endif
|
||||
#else // common linux/unix all have the stat system call
|
||||
struct stat buffer;
|
||||
return (::stat(filename.c_str(), &buffer) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// avoid warning about unreachable statement at the end of filesize()
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4702)
|
||||
#endif
|
||||
|
||||
// Return file size according to open FILE* object
|
||||
SPDLOG_INLINE size_t filesize(FILE *f) {
|
||||
if (f == nullptr) {
|
||||
throw_spdlog_ex("Failed getting file size. fd is null");
|
||||
}
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
int fd = ::_fileno(f);
|
||||
#if defined(_WIN64) // 64 bits
|
||||
__int64 ret = ::_filelengthi64(fd);
|
||||
if (ret >= 0) {
|
||||
return static_cast<size_t>(ret);
|
||||
}
|
||||
|
||||
#else // windows 32 bits
|
||||
long ret = ::_filelength(fd);
|
||||
if (ret >= 0) {
|
||||
return static_cast<size_t>(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // unix
|
||||
// OpenBSD and AIX doesn't compile with :: before the fileno(..)
|
||||
#if defined(__OpenBSD__) || defined(_AIX)
|
||||
int fd = fileno(f);
|
||||
#else
|
||||
int fd = ::fileno(f);
|
||||
#endif
|
||||
// 64 bits(but not in osx, linux/musl or cygwin, where fstat64 is deprecated)
|
||||
#if ((defined(__linux__) && defined(__GLIBC__)) || defined(__sun) || defined(_AIX)) && \
|
||||
(defined(__LP64__) || defined(_LP64))
|
||||
struct stat64 st;
|
||||
if (::fstat64(fd, &st) == 0) {
|
||||
return static_cast<size_t>(st.st_size);
|
||||
}
|
||||
#else // other unix or linux 32 bits or cygwin
|
||||
struct stat st;
|
||||
if (::fstat(fd, &st) == 0) {
|
||||
return static_cast<size_t>(st.st_size);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
throw_spdlog_ex("Failed getting file size from fd", errno);
|
||||
return 0; // will not be reached.
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// Return utc offset in minutes or throw spdlog_ex on failure
|
||||
SPDLOG_INLINE int utc_minutes_offset(const std::tm &tm) {
|
||||
#ifdef _WIN32
|
||||
#if _WIN32_WINNT < _WIN32_WINNT_WS08
|
||||
TIME_ZONE_INFORMATION tzinfo;
|
||||
auto rv = ::GetTimeZoneInformation(&tzinfo);
|
||||
#else
|
||||
DYNAMIC_TIME_ZONE_INFORMATION tzinfo;
|
||||
auto rv = ::GetDynamicTimeZoneInformation(&tzinfo);
|
||||
#endif
|
||||
if (rv == TIME_ZONE_ID_INVALID) throw_spdlog_ex("Failed getting timezone info. ", errno);
|
||||
|
||||
int offset = -tzinfo.Bias;
|
||||
if (tm.tm_isdst) {
|
||||
offset -= tzinfo.DaylightBias;
|
||||
} else {
|
||||
offset -= tzinfo.StandardBias;
|
||||
}
|
||||
return offset;
|
||||
#else
|
||||
|
||||
#if defined(sun) || defined(__sun) || defined(_AIX) || \
|
||||
(defined(__NEWLIB__) && !defined(__TM_GMTOFF)) || \
|
||||
(!defined(_BSD_SOURCE) && !defined(_GNU_SOURCE))
|
||||
// 'tm_gmtoff' field is BSD extension and it's missing on SunOS/Solaris
|
||||
struct helper {
|
||||
static long int calculate_gmt_offset(const std::tm &localtm = details::os::localtime(),
|
||||
const std::tm &gmtm = details::os::gmtime()) {
|
||||
int local_year = localtm.tm_year + (1900 - 1);
|
||||
int gmt_year = gmtm.tm_year + (1900 - 1);
|
||||
|
||||
long int days = (
|
||||
// difference in day of year
|
||||
localtm.tm_yday -
|
||||
gmtm.tm_yday
|
||||
|
||||
// + intervening leap days
|
||||
+ ((local_year >> 2) - (gmt_year >> 2)) - (local_year / 100 - gmt_year / 100) +
|
||||
((local_year / 100 >> 2) - (gmt_year / 100 >> 2))
|
||||
|
||||
// + difference in years * 365 */
|
||||
+ static_cast<long int>(local_year - gmt_year) * 365);
|
||||
|
||||
long int hours = (24 * days) + (localtm.tm_hour - gmtm.tm_hour);
|
||||
long int mins = (60 * hours) + (localtm.tm_min - gmtm.tm_min);
|
||||
long int secs = (60 * mins) + (localtm.tm_sec - gmtm.tm_sec);
|
||||
|
||||
return secs;
|
||||
}
|
||||
};
|
||||
|
||||
auto offset_seconds = helper::calculate_gmt_offset(tm);
|
||||
#else
|
||||
auto offset_seconds = tm.tm_gmtoff;
|
||||
#endif
|
||||
|
||||
return static_cast<int>(offset_seconds / 60);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return current thread id as size_t
|
||||
// It exists because the std::this_thread::get_id() is much slower(especially
|
||||
// under VS 2013)
|
||||
SPDLOG_INLINE size_t _thread_id() SPDLOG_NOEXCEPT {
|
||||
#ifdef _WIN32
|
||||
return static_cast<size_t>(::GetCurrentThreadId());
|
||||
#elif defined(__linux__)
|
||||
#if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
|
||||
#define SYS_gettid __NR_gettid
|
||||
#endif
|
||||
return static_cast<size_t>(::syscall(SYS_gettid));
|
||||
#elif defined(_AIX)
|
||||
struct __pthrdsinfo buf;
|
||||
int reg_size = 0;
|
||||
pthread_t pt = pthread_self();
|
||||
int retval = pthread_getthrds_np(&pt, PTHRDSINFO_QUERY_TID, &buf, sizeof(buf), NULL, ®_size);
|
||||
int tid = (!retval) ? buf.__pi_tid : 0;
|
||||
return static_cast<size_t>(tid);
|
||||
#elif defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
return static_cast<size_t>(::pthread_getthreadid_np());
|
||||
#elif defined(__NetBSD__)
|
||||
return static_cast<size_t>(::_lwp_self());
|
||||
#elif defined(__OpenBSD__)
|
||||
return static_cast<size_t>(::getthrid());
|
||||
#elif defined(__sun)
|
||||
return static_cast<size_t>(::thr_self());
|
||||
#elif __APPLE__
|
||||
uint64_t tid;
|
||||
// There is no pthread_threadid_np prior to Mac OS X 10.6, and it is not supported on any PPC,
|
||||
// including 10.6.8 Rosetta. __POWERPC__ is Apple-specific define encompassing ppc and ppc64.
|
||||
#ifdef MAC_OS_X_VERSION_MAX_ALLOWED
|
||||
{
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 1060) || defined(__POWERPC__)
|
||||
tid = pthread_mach_thread_np(pthread_self());
|
||||
#elif MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
if (&pthread_threadid_np) {
|
||||
pthread_threadid_np(nullptr, &tid);
|
||||
} else {
|
||||
tid = pthread_mach_thread_np(pthread_self());
|
||||
}
|
||||
#else
|
||||
pthread_threadid_np(nullptr, &tid);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
pthread_threadid_np(nullptr, &tid);
|
||||
#endif
|
||||
return static_cast<size_t>(tid);
|
||||
#else // Default to standard C++11 (other Unix)
|
||||
return static_cast<size_t>(std::hash<std::thread::id>()(std::this_thread::get_id()));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return current thread id as size_t (from thread local storage)
|
||||
SPDLOG_INLINE size_t thread_id() SPDLOG_NOEXCEPT {
|
||||
#if defined(SPDLOG_NO_TLS)
|
||||
return _thread_id();
|
||||
#else // cache thread id in tls
|
||||
static thread_local const size_t tid = _thread_id();
|
||||
return tid;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This is avoid msvc issue in sleep_for that happens if the clock changes.
|
||||
// See https://github.com/gabime/spdlog/issues/609
|
||||
SPDLOG_INLINE void sleep_for_millis(unsigned int milliseconds) SPDLOG_NOEXCEPT {
|
||||
#if defined(_WIN32)
|
||||
::Sleep(milliseconds);
|
||||
#else
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
|
||||
#endif
|
||||
}
|
||||
|
||||
// wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined)
|
||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
|
||||
SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) {
|
||||
memory_buf_t buf;
|
||||
wstr_to_utf8buf(filename, buf);
|
||||
return SPDLOG_BUF_TO_STRING(buf);
|
||||
}
|
||||
#else
|
||||
SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) { return filename; }
|
||||
#endif
|
||||
|
||||
SPDLOG_INLINE int pid() SPDLOG_NOEXCEPT {
|
||||
#ifdef _WIN32
|
||||
return conditional_static_cast<int>(::GetCurrentProcessId());
|
||||
#else
|
||||
return conditional_static_cast<int>(::getpid());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Determine if the terminal supports colors
|
||||
// Based on: https://github.com/agauniyal/rang/
|
||||
SPDLOG_INLINE bool is_color_terminal() SPDLOG_NOEXCEPT {
|
||||
#ifdef _WIN32
|
||||
return true;
|
||||
#else
|
||||
|
||||
static const bool result = []() {
|
||||
const char *env_colorterm_p = std::getenv("COLORTERM");
|
||||
if (env_colorterm_p != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static constexpr std::array<const char *, 16> terms = {
|
||||
{"ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", "linux", "msys",
|
||||
"putty", "rxvt", "screen", "vt100", "xterm", "alacritty", "vt102"}};
|
||||
|
||||
const char *env_term_p = std::getenv("TERM");
|
||||
if (env_term_p == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return std::any_of(terms.begin(), terms.end(), [&](const char *term) {
|
||||
return std::strstr(env_term_p, term) != nullptr;
|
||||
});
|
||||
}();
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Determine if the terminal attached
|
||||
// Source: https://github.com/agauniyal/rang/
|
||||
SPDLOG_INLINE bool in_terminal(FILE *file) SPDLOG_NOEXCEPT {
|
||||
#ifdef _WIN32
|
||||
return ::_isatty(_fileno(file)) != 0;
|
||||
#else
|
||||
return ::isatty(fileno(file)) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
|
||||
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)()) / 2 - 1) {
|
||||
throw_spdlog_ex("UTF-16 string is too big to be converted to UTF-8");
|
||||
}
|
||||
|
||||
int wstr_size = static_cast<int>(wstr.size());
|
||||
if (wstr_size == 0) {
|
||||
target.resize(0);
|
||||
return;
|
||||
}
|
||||
|
||||
int result_size = static_cast<int>(target.capacity());
|
||||
if ((wstr_size + 1) * 2 > result_size) {
|
||||
result_size =
|
||||
::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
if (result_size > 0) {
|
||||
target.resize(result_size);
|
||||
result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, target.data(),
|
||||
result_size, NULL, NULL);
|
||||
|
||||
if (result_size > 0) {
|
||||
target.resize(result_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw_spdlog_ex(
|
||||
fmt_lib::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()));
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) {
|
||||
if (str.size() > static_cast<size_t>((std::numeric_limits<int>::max)()) - 1) {
|
||||
throw_spdlog_ex("UTF-8 string is too big to be converted to UTF-16");
|
||||
}
|
||||
|
||||
int str_size = static_cast<int>(str.size());
|
||||
if (str_size == 0) {
|
||||
target.resize(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// find the size to allocate for the result buffer
|
||||
int result_size =
|
||||
::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, NULL, 0);
|
||||
|
||||
if (result_size > 0) {
|
||||
target.resize(result_size);
|
||||
result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size,
|
||||
target.data(), result_size);
|
||||
if (result_size > 0) {
|
||||
assert(result_size == target.size());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw_spdlog_ex(
|
||||
fmt_lib::format("MultiByteToWideChar failed. Last error: {}", ::GetLastError()));
|
||||
}
|
||||
#endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) &&
|
||||
// defined(_WIN32)
|
||||
|
||||
// return true on success
|
||||
static SPDLOG_INLINE bool mkdir_(const filename_t &path) {
|
||||
#ifdef _WIN32
|
||||
#ifdef SPDLOG_WCHAR_FILENAMES
|
||||
return ::_wmkdir(path.c_str()) == 0;
|
||||
#else
|
||||
return ::_mkdir(path.c_str()) == 0;
|
||||
#endif
|
||||
#else
|
||||
return ::mkdir(path.c_str(), mode_t(0755)) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// create the given directory - and all directories leading to it
|
||||
// return true on success or if the directory already exists
|
||||
SPDLOG_INLINE bool create_dir(const filename_t &path) {
|
||||
if (path_exists(path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (path.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t search_offset = 0;
|
||||
do {
|
||||
auto token_pos = path.find_first_of(folder_seps_filename, search_offset);
|
||||
// treat the entire path as a folder if no folder separator not found
|
||||
if (token_pos == filename_t::npos) {
|
||||
token_pos = path.size();
|
||||
}
|
||||
|
||||
auto subdir = path.substr(0, token_pos);
|
||||
|
||||
if (!subdir.empty() && !path_exists(subdir) && !mkdir_(subdir)) {
|
||||
return false; // return error if failed creating dir
|
||||
}
|
||||
search_offset = token_pos + 1;
|
||||
} while (search_offset < path.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return directory name from given path or empty string
|
||||
// "abc/file" => "abc"
|
||||
// "abc/" => "abc"
|
||||
// "abc" => ""
|
||||
// "abc///" => "abc//"
|
||||
SPDLOG_INLINE filename_t dir_name(const filename_t &path) {
|
||||
auto pos = path.find_last_of(folder_seps_filename);
|
||||
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
|
||||
}
|
||||
|
||||
// Do fsync by FILE handlerpointer
|
||||
// Return true on success
|
||||
SPDLOG_INLINE bool fsync(FILE *fp) {
|
||||
#ifdef _WIN32
|
||||
return FlushFileBuffers(reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(fp)))) != 0;
|
||||
#else
|
||||
return ::fsync(fileno(fp)) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace os
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
123
third_party/spdlog_headers/spdlog/details/os.h
vendored
Normal file
123
third_party/spdlog_headers/spdlog/details/os.h
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ctime> // std::time_t
|
||||
#include <spdlog/common.h>
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
namespace os {
|
||||
|
||||
SPDLOG_API spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT;
|
||||
|
||||
SPDLOG_API std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT;
|
||||
|
||||
SPDLOG_API std::tm localtime() SPDLOG_NOEXCEPT;
|
||||
|
||||
SPDLOG_API std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT;
|
||||
|
||||
SPDLOG_API std::tm gmtime() SPDLOG_NOEXCEPT;
|
||||
|
||||
// eol definition
|
||||
#if !defined(SPDLOG_EOL)
|
||||
#ifdef _WIN32
|
||||
#define SPDLOG_EOL "\r\n"
|
||||
#else
|
||||
#define SPDLOG_EOL "\n"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SPDLOG_CONSTEXPR static const char *default_eol = SPDLOG_EOL;
|
||||
|
||||
// folder separator
|
||||
#if !defined(SPDLOG_FOLDER_SEPS)
|
||||
#ifdef _WIN32
|
||||
#define SPDLOG_FOLDER_SEPS "\\/"
|
||||
#else
|
||||
#define SPDLOG_FOLDER_SEPS "/"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SPDLOG_CONSTEXPR static const char folder_seps[] = SPDLOG_FOLDER_SEPS;
|
||||
SPDLOG_CONSTEXPR static const filename_t::value_type folder_seps_filename[] =
|
||||
SPDLOG_FILENAME_T(SPDLOG_FOLDER_SEPS);
|
||||
|
||||
// fopen_s on non windows for writing
|
||||
SPDLOG_API bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode);
|
||||
|
||||
// Remove filename. return 0 on success
|
||||
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)
|
||||
SPDLOG_API int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
|
||||
|
||||
SPDLOG_API int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT;
|
||||
|
||||
// Return if file exists.
|
||||
SPDLOG_API bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
|
||||
|
||||
// Return file size according to open FILE* object
|
||||
SPDLOG_API size_t filesize(FILE *f);
|
||||
|
||||
// Return utc offset in minutes or throw spdlog_ex on failure
|
||||
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)
|
||||
SPDLOG_API size_t _thread_id() SPDLOG_NOEXCEPT;
|
||||
|
||||
// Return current thread id as size_t (from thread local storage)
|
||||
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
|
||||
SPDLOG_API void sleep_for_millis(unsigned int milliseconds) SPDLOG_NOEXCEPT;
|
||||
|
||||
SPDLOG_API std::string filename_to_str(const filename_t &filename);
|
||||
|
||||
SPDLOG_API int pid() SPDLOG_NOEXCEPT;
|
||||
|
||||
// Determine if the terminal supports colors
|
||||
// Source: https://github.com/agauniyal/rang/
|
||||
SPDLOG_API bool is_color_terminal() SPDLOG_NOEXCEPT;
|
||||
|
||||
// Determine if the terminal attached
|
||||
// Source: https://github.com/agauniyal/rang/
|
||||
SPDLOG_API bool in_terminal(FILE *file) SPDLOG_NOEXCEPT;
|
||||
|
||||
#if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
|
||||
SPDLOG_API void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target);
|
||||
|
||||
SPDLOG_API void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target);
|
||||
#endif
|
||||
|
||||
// Return directory name from given path or empty string
|
||||
// "abc/file" => "abc"
|
||||
// "abc/" => "abc"
|
||||
// "abc" => ""
|
||||
// "abc///" => "abc//"
|
||||
SPDLOG_API filename_t dir_name(const filename_t &path);
|
||||
|
||||
// Create a dir from the given path.
|
||||
// Return true if succeeded or if this dir already exists.
|
||||
SPDLOG_API bool create_dir(const 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);
|
||||
|
||||
// Do fsync by FILE objectpointer.
|
||||
// Return true on success.
|
||||
SPDLOG_API bool fsync(FILE *fp);
|
||||
|
||||
} // namespace os
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "os-inl.h"
|
||||
#endif
|
||||
26
third_party/spdlog_headers/spdlog/details/periodic_worker-inl.h
vendored
Normal file
26
third_party/spdlog_headers/spdlog/details/periodic_worker-inl.h
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SPDLOG_HEADER_ONLY
|
||||
#include <spdlog/details/periodic_worker.h>
|
||||
#endif
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
// stop the worker thread and join it
|
||||
SPDLOG_INLINE periodic_worker::~periodic_worker() {
|
||||
if (worker_thread_.joinable()) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
active_ = false;
|
||||
}
|
||||
cv_.notify_one();
|
||||
worker_thread_.join();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
58
third_party/spdlog_headers/spdlog/details/periodic_worker.h
vendored
Normal file
58
third_party/spdlog_headers/spdlog/details/periodic_worker.h
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
// periodic worker thread - periodically executes the given callback function.
|
||||
//
|
||||
// RAII over the owned thread:
|
||||
// creates the thread on construction.
|
||||
// stops and joins the thread on destruction (if the thread is executing a callback, wait for it
|
||||
// to finish first).
|
||||
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
class SPDLOG_API periodic_worker {
|
||||
public:
|
||||
template <typename Rep, typename Period>
|
||||
periodic_worker(const std::function<void()> &callback_fun,
|
||||
std::chrono::duration<Rep, Period> interval) {
|
||||
active_ = (interval > std::chrono::duration<Rep, Period>::zero());
|
||||
if (!active_) {
|
||||
return;
|
||||
}
|
||||
|
||||
worker_thread_ = std::thread([this, callback_fun, interval]() {
|
||||
for (;;) {
|
||||
std::unique_lock<std::mutex> lock(this->mutex_);
|
||||
if (this->cv_.wait_for(lock, interval, [this] { return !this->active_; })) {
|
||||
return; // active_ == false, so exit this thread
|
||||
}
|
||||
callback_fun();
|
||||
}
|
||||
});
|
||||
}
|
||||
std::thread &get_thread() { return worker_thread_; }
|
||||
periodic_worker(const periodic_worker &) = delete;
|
||||
periodic_worker &operator=(const periodic_worker &) = delete;
|
||||
// stop the worker thread and join it
|
||||
~periodic_worker();
|
||||
|
||||
private:
|
||||
bool active_;
|
||||
std::thread worker_thread_;
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cv_;
|
||||
};
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "periodic_worker-inl.h"
|
||||
#endif
|
||||
281
third_party/spdlog_headers/spdlog/details/registry-inl.h
vendored
Normal file
281
third_party/spdlog_headers/spdlog/details/registry-inl.h
vendored
Normal file
@@ -0,0 +1,281 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SPDLOG_HEADER_ONLY
|
||||
#include <spdlog/details/registry.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/details/periodic_worker.h>
|
||||
#include <spdlog/logger.h>
|
||||
#include <spdlog/pattern_formatter.h>
|
||||
|
||||
#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
|
||||
// support for the default stdout color logger
|
||||
#ifdef _WIN32
|
||||
#include <spdlog/sinks/wincolor_sink.h>
|
||||
#else
|
||||
#include <spdlog/sinks/ansicolor_sink.h>
|
||||
#endif
|
||||
#endif // SPDLOG_DISABLE_DEFAULT_LOGGER
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
SPDLOG_INLINE registry::registry()
|
||||
: formatter_(new pattern_formatter()) {
|
||||
#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
|
||||
// create default logger (ansicolor_stdout_sink_mt or wincolor_stdout_sink_mt in windows).
|
||||
#ifdef _WIN32
|
||||
auto color_sink = std::make_shared<sinks::wincolor_stdout_sink_mt>();
|
||||
#else
|
||||
auto color_sink = std::make_shared<sinks::ansicolor_stdout_sink_mt>();
|
||||
#endif
|
||||
|
||||
const char *default_logger_name = "";
|
||||
default_logger_ = std::make_shared<spdlog::logger>(default_logger_name, std::move(color_sink));
|
||||
loggers_[default_logger_name] = default_logger_;
|
||||
|
||||
#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_);
|
||||
register_logger_(std::move(new_logger));
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr<logger> new_logger) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
new_logger->set_formatter(formatter_->clone());
|
||||
|
||||
if (err_handler_) {
|
||||
new_logger->set_error_handler(err_handler_);
|
||||
}
|
||||
|
||||
// set new level according to previously configured level or default level
|
||||
auto it = log_levels_.find(new_logger->name());
|
||||
auto new_level = it != log_levels_.end() ? it->second : global_log_level_;
|
||||
new_logger->set_level(new_level);
|
||||
|
||||
new_logger->flush_on(flush_level_);
|
||||
|
||||
if (backtrace_n_messages_ > 0) {
|
||||
new_logger->enable_backtrace(backtrace_n_messages_);
|
||||
}
|
||||
|
||||
if (automatic_registration_) {
|
||||
register_logger_(std::move(new_logger));
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE std::shared_ptr<logger> registry::get(const std::string &logger_name) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
auto found = loggers_.find(logger_name);
|
||||
return found == loggers_.end() ? nullptr : found->second;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201703L // C++17
|
||||
SPDLOG_INLINE std::shared_ptr<logger> registry::get(std::string_view logger_name) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (const auto &[key, val] : loggers_) {
|
||||
if (key == logger_name) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE std::shared_ptr<logger> registry::get(const char *logger_name) {
|
||||
return get(std::string_view(logger_name));
|
||||
}
|
||||
#endif
|
||||
|
||||
SPDLOG_INLINE std::shared_ptr<logger> registry::default_logger() {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
return default_logger_;
|
||||
}
|
||||
|
||||
// Return raw ptr to the default logger.
|
||||
// To be used directly by the spdlog default api (e.g. spdlog::info)
|
||||
// This make the default API faster, but cannot be used concurrently with set_default_logger().
|
||||
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
|
||||
SPDLOG_INLINE logger *registry::get_default_raw() { return default_logger_.get(); }
|
||||
|
||||
// set default logger.
|
||||
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
|
||||
SPDLOG_INLINE void registry::set_default_logger(std::shared_ptr<logger> new_default_logger) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
// remove previous default logger from the map
|
||||
if (default_logger_ != nullptr) {
|
||||
loggers_.erase(default_logger_->name());
|
||||
}
|
||||
if (new_default_logger != nullptr) {
|
||||
loggers_[new_default_logger->name()] = new_default_logger;
|
||||
}
|
||||
default_logger_ = std::move(new_default_logger);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::set_tp(std::shared_ptr<thread_pool> tp) {
|
||||
std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
|
||||
tp_ = std::move(tp);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE std::shared_ptr<thread_pool> registry::get_tp() {
|
||||
std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
|
||||
return tp_;
|
||||
}
|
||||
|
||||
// Set global formatter. Each sink in each logger will get a clone of this object
|
||||
SPDLOG_INLINE void registry::set_formatter(std::unique_ptr<formatter> formatter) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
formatter_ = std::move(formatter);
|
||||
for (auto &l : loggers_) {
|
||||
l.second->set_formatter(formatter_->clone());
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::enable_backtrace(size_t n_messages) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
backtrace_n_messages_ = n_messages;
|
||||
|
||||
for (auto &l : loggers_) {
|
||||
l.second->enable_backtrace(n_messages);
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::disable_backtrace() {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
backtrace_n_messages_ = 0;
|
||||
for (auto &l : loggers_) {
|
||||
l.second->disable_backtrace();
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::set_level(level::level_enum log_level) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_) {
|
||||
l.second->set_level(log_level);
|
||||
}
|
||||
global_log_level_ = log_level;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::flush_on(level::level_enum log_level) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_) {
|
||||
l.second->flush_on(log_level);
|
||||
}
|
||||
flush_level_ = log_level;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::set_error_handler(err_handler handler) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_) {
|
||||
l.second->set_error_handler(handler);
|
||||
}
|
||||
err_handler_ = std::move(handler);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::apply_all(
|
||||
const std::function<void(const std::shared_ptr<logger>)> &fun) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_) {
|
||||
fun(l.second);
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::flush_all() {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_) {
|
||||
l.second->flush();
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::drop(const std::string &logger_name) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
auto is_default_logger = default_logger_ && default_logger_->name() == logger_name;
|
||||
loggers_.erase(logger_name);
|
||||
if (is_default_logger) {
|
||||
default_logger_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::drop_all() {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
loggers_.clear();
|
||||
default_logger_.reset();
|
||||
}
|
||||
|
||||
// clean all resources and threads started by the registry
|
||||
SPDLOG_INLINE void registry::shutdown() {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(flusher_mutex_);
|
||||
periodic_flusher_.reset();
|
||||
}
|
||||
|
||||
drop_all();
|
||||
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
|
||||
tp_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE std::recursive_mutex ®istry::tp_mutex() { return tp_mutex_; }
|
||||
|
||||
SPDLOG_INLINE void registry::set_automatic_registration(bool automatic_registration) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
automatic_registration_ = automatic_registration;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::set_levels(log_levels levels, level::level_enum *global_level) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
log_levels_ = std::move(levels);
|
||||
auto global_level_requested = global_level != nullptr;
|
||||
global_log_level_ = global_level_requested ? *global_level : global_log_level_;
|
||||
|
||||
for (auto &logger : loggers_) {
|
||||
auto logger_entry = log_levels_.find(logger.first);
|
||||
if (logger_entry != log_levels_.end()) {
|
||||
logger.second->set_level(logger_entry->second);
|
||||
} else if (global_level_requested) {
|
||||
logger.second->set_level(*global_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE registry ®istry::instance() {
|
||||
static registry s_instance;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::apply_logger_env_levels(std::shared_ptr<logger> new_logger) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
auto it = log_levels_.find(new_logger->name());
|
||||
auto new_level = it != log_levels_.end() ? it->second : global_log_level_;
|
||||
new_logger->set_level(new_level);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::throw_if_exists_(const std::string &logger_name) {
|
||||
if (loggers_.find(logger_name) != loggers_.end()) {
|
||||
throw_spdlog_ex("logger with name '" + logger_name + "' already exists");
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::register_logger_(std::shared_ptr<logger> new_logger) {
|
||||
auto logger_name = new_logger->name();
|
||||
throw_if_exists_(logger_name);
|
||||
loggers_[logger_name] = std::move(new_logger);
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
135
third_party/spdlog_headers/spdlog/details/registry.h
vendored
Normal file
135
third_party/spdlog_headers/spdlog/details/registry.h
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
// Loggers registry of unique name->logger pointer
|
||||
// An attempt to create a logger with an already existing name will result with spdlog_ex exception.
|
||||
// If user requests a non existing logger, nullptr will be returned
|
||||
// This class is thread safe
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/details/periodic_worker.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#if __cplusplus >= 201703L // C++17
|
||||
#include <string_view>
|
||||
#endif
|
||||
|
||||
namespace spdlog {
|
||||
class logger;
|
||||
|
||||
namespace details {
|
||||
class thread_pool;
|
||||
|
||||
class SPDLOG_API registry {
|
||||
public:
|
||||
using log_levels = std::unordered_map<std::string, level::level_enum>;
|
||||
registry(const registry &) = delete;
|
||||
registry &operator=(const registry &) = delete;
|
||||
|
||||
void register_logger(std::shared_ptr<logger> new_logger);
|
||||
void initialize_logger(std::shared_ptr<logger> new_logger);
|
||||
std::shared_ptr<logger> get(const std::string &logger_name);
|
||||
#if __cplusplus >= 201703L // C++17
|
||||
std::shared_ptr<logger> get(std::string_view logger_name);
|
||||
std::shared_ptr<logger> get(const char *logger_name);
|
||||
#endif
|
||||
std::shared_ptr<logger> default_logger();
|
||||
|
||||
// Return raw ptr to the default logger.
|
||||
// To be used directly by the spdlog default api (e.g. spdlog::info)
|
||||
// This make the default API faster, but cannot be used concurrently with set_default_logger().
|
||||
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from
|
||||
// another.
|
||||
logger *get_default_raw();
|
||||
|
||||
// set default logger.
|
||||
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
|
||||
void set_default_logger(std::shared_ptr<logger> new_default_logger);
|
||||
|
||||
void set_tp(std::shared_ptr<thread_pool> tp);
|
||||
|
||||
std::shared_ptr<thread_pool> get_tp();
|
||||
|
||||
// Set global formatter. Each sink in each logger will get a clone of this object
|
||||
void set_formatter(std::unique_ptr<formatter> formatter);
|
||||
|
||||
void enable_backtrace(size_t n_messages);
|
||||
|
||||
void disable_backtrace();
|
||||
|
||||
void set_level(level::level_enum log_level);
|
||||
|
||||
void flush_on(level::level_enum log_level);
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
void flush_every(std::chrono::duration<Rep, Period> interval) {
|
||||
std::lock_guard<std::mutex> lock(flusher_mutex_);
|
||||
auto clbk = [this]() { this->flush_all(); };
|
||||
periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
|
||||
}
|
||||
|
||||
std::unique_ptr<periodic_worker> &get_flusher() {
|
||||
std::lock_guard<std::mutex> lock(flusher_mutex_);
|
||||
return periodic_flusher_;
|
||||
}
|
||||
|
||||
void set_error_handler(err_handler handler);
|
||||
|
||||
void apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun);
|
||||
|
||||
void flush_all();
|
||||
|
||||
void drop(const std::string &logger_name);
|
||||
|
||||
void drop_all();
|
||||
|
||||
// clean all resources and threads started by the registry
|
||||
void shutdown();
|
||||
|
||||
std::recursive_mutex &tp_mutex();
|
||||
|
||||
void set_automatic_registration(bool automatic_registration);
|
||||
|
||||
// set levels for all existing/future loggers. global_level can be null if should not set.
|
||||
void set_levels(log_levels levels, level::level_enum *global_level);
|
||||
|
||||
static registry &instance();
|
||||
|
||||
void apply_logger_env_levels(std::shared_ptr<logger> new_logger);
|
||||
|
||||
private:
|
||||
registry();
|
||||
~registry();
|
||||
|
||||
void throw_if_exists_(const std::string &logger_name);
|
||||
void register_logger_(std::shared_ptr<logger> new_logger);
|
||||
bool set_level_from_cfg_(logger *logger);
|
||||
std::mutex logger_map_mutex_, flusher_mutex_;
|
||||
std::recursive_mutex tp_mutex_;
|
||||
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
|
||||
log_levels log_levels_;
|
||||
std::unique_ptr<formatter> formatter_;
|
||||
spdlog::level::level_enum global_log_level_ = level::info;
|
||||
level::level_enum flush_level_ = level::off;
|
||||
err_handler err_handler_;
|
||||
std::shared_ptr<thread_pool> tp_;
|
||||
std::unique_ptr<periodic_worker> periodic_flusher_;
|
||||
std::shared_ptr<logger> default_logger_;
|
||||
bool automatic_registration_ = true;
|
||||
size_t backtrace_n_messages_ = 0;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "registry-inl.h"
|
||||
#endif
|
||||
22
third_party/spdlog_headers/spdlog/details/synchronous_factory.h
vendored
Normal file
22
third_party/spdlog_headers/spdlog/details/synchronous_factory.h
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "registry.h"
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
// Default logger factory- creates synchronous loggers
|
||||
class logger;
|
||||
|
||||
struct synchronous_factory {
|
||||
template <typename Sink, typename... SinkArgs>
|
||||
static std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&...args) {
|
||||
auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
|
||||
auto new_logger = std::make_shared<spdlog::logger>(std::move(logger_name), std::move(sink));
|
||||
details::registry::instance().initialize_logger(new_logger);
|
||||
return new_logger;
|
||||
}
|
||||
};
|
||||
} // namespace spdlog
|
||||
3323
third_party/spdlog_headers/spdlog/fmt/bundled/core.h
vendored
Normal file
3323
third_party/spdlog_headers/spdlog/fmt/bundled/core.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1723
third_party/spdlog_headers/spdlog/fmt/bundled/format-inl.h
vendored
Normal file
1723
third_party/spdlog_headers/spdlog/fmt/bundled/format-inl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4217
third_party/spdlog_headers/spdlog/fmt/bundled/format.h
vendored
Normal file
4217
third_party/spdlog_headers/spdlog/fmt/bundled/format.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
34
third_party/spdlog_headers/spdlog/fmt/fmt.h
vendored
Normal file
34
third_party/spdlog_headers/spdlog/fmt/fmt.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Copyright(c) 2016-2018 Gabi Melman.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// Include a bundled header-only copy of fmtlib or an external one.
|
||||
// By default spdlog include its own copy.
|
||||
//
|
||||
#include <spdlog/tweakme.h>
|
||||
|
||||
#if defined(SPDLOG_USE_STD_FORMAT) // SPDLOG_USE_STD_FORMAT is defined - use std::format
|
||||
#include <format>
|
||||
#elif !defined(SPDLOG_FMT_EXTERNAL)
|
||||
#if !defined(SPDLOG_COMPILED_LIB) && !defined(FMT_HEADER_ONLY)
|
||||
#define FMT_HEADER_ONLY
|
||||
#endif
|
||||
#ifndef FMT_USE_WINDOWS_H
|
||||
#define FMT_USE_WINDOWS_H 0
|
||||
#endif
|
||||
// enable the 'n' flag in for backward compatibility with fmt 6.x
|
||||
#define FMT_DEPRECATED_N_SPECIFIER
|
||||
// enable ostream formatting for backward compatibility with fmt 8.x
|
||||
#define FMT_DEPRECATED_OSTREAM
|
||||
|
||||
#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
|
||||
17
third_party/spdlog_headers/spdlog/formatter.h
vendored
Normal file
17
third_party/spdlog_headers/spdlog/formatter.h
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/details/log_msg.h>
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
class formatter {
|
||||
public:
|
||||
virtual ~formatter() = default;
|
||||
virtual void format(const details::log_msg &msg, memory_buf_t &dest) = 0;
|
||||
virtual std::unique_ptr<formatter> clone() const = 0;
|
||||
};
|
||||
} // namespace spdlog
|
||||
198
third_party/spdlog_headers/spdlog/logger-inl.h
vendored
Normal file
198
third_party/spdlog_headers/spdlog/logger-inl.h
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
// 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/logger.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/details/backtracer.h>
|
||||
#include <spdlog/pattern_formatter.h>
|
||||
#include <spdlog/sinks/sink.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
// public methods
|
||||
SPDLOG_INLINE logger::logger(const logger &other)
|
||||
: name_(other.name_),
|
||||
sinks_(other.sinks_),
|
||||
level_(other.level_.load(std::memory_order_relaxed)),
|
||||
flush_level_(other.flush_level_.load(std::memory_order_relaxed)),
|
||||
custom_err_handler_(other.custom_err_handler_),
|
||||
tracer_(other.tracer_) {}
|
||||
|
||||
SPDLOG_INLINE logger::logger(logger &&other) SPDLOG_NOEXCEPT
|
||||
: name_(std::move(other.name_)),
|
||||
sinks_(std::move(other.sinks_)),
|
||||
level_(other.level_.load(std::memory_order_relaxed)),
|
||||
flush_level_(other.flush_level_.load(std::memory_order_relaxed)),
|
||||
custom_err_handler_(std::move(other.custom_err_handler_)),
|
||||
tracer_(std::move(other.tracer_))
|
||||
|
||||
{}
|
||||
|
||||
SPDLOG_INLINE logger &logger::operator=(logger other) SPDLOG_NOEXCEPT {
|
||||
this->swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void logger::swap(spdlog::logger &other) SPDLOG_NOEXCEPT {
|
||||
name_.swap(other.name_);
|
||||
sinks_.swap(other.sinks_);
|
||||
|
||||
// swap level_
|
||||
auto other_level = other.level_.load();
|
||||
auto my_level = level_.exchange(other_level);
|
||||
other.level_.store(my_level);
|
||||
|
||||
// swap flush level_
|
||||
other_level = other.flush_level_.load();
|
||||
my_level = flush_level_.exchange(other_level);
|
||||
other.flush_level_.store(my_level);
|
||||
|
||||
custom_err_handler_.swap(other.custom_err_handler_);
|
||||
std::swap(tracer_, other.tracer_);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void swap(logger &a, logger &b) { a.swap(b); }
|
||||
|
||||
SPDLOG_INLINE void logger::set_level(level::level_enum log_level) { level_.store(log_level); }
|
||||
|
||||
SPDLOG_INLINE level::level_enum logger::level() const {
|
||||
return static_cast<level::level_enum>(level_.load(std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
SPDLOG_INLINE const std::string &logger::name() const { return name_; }
|
||||
|
||||
// set formatting for the sinks in this logger.
|
||||
// each sink will get a separate instance of the formatter object.
|
||||
SPDLOG_INLINE void logger::set_formatter(std::unique_ptr<formatter> f) {
|
||||
for (auto it = sinks_.begin(); it != sinks_.end(); ++it) {
|
||||
if (std::next(it) == sinks_.end()) {
|
||||
// last element - we can be move it.
|
||||
(*it)->set_formatter(std::move(f));
|
||||
break; // to prevent clang-tidy warning
|
||||
} else {
|
||||
(*it)->set_formatter(f->clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void logger::set_pattern(std::string pattern, pattern_time_type time_type) {
|
||||
auto new_formatter = details::make_unique<pattern_formatter>(std::move(pattern), time_type);
|
||||
set_formatter(std::move(new_formatter));
|
||||
}
|
||||
|
||||
// create new backtrace sink and move to it all our child sinks
|
||||
SPDLOG_INLINE void logger::enable_backtrace(size_t n_messages) { tracer_.enable(n_messages); }
|
||||
|
||||
// restore orig sinks and level and delete the backtrace sink
|
||||
SPDLOG_INLINE void logger::disable_backtrace() { tracer_.disable(); }
|
||||
|
||||
SPDLOG_INLINE void logger::dump_backtrace() { dump_backtrace_(); }
|
||||
|
||||
// flush functions
|
||||
SPDLOG_INLINE void logger::flush() { flush_(); }
|
||||
|
||||
SPDLOG_INLINE void logger::flush_on(level::level_enum log_level) { flush_level_.store(log_level); }
|
||||
|
||||
SPDLOG_INLINE level::level_enum logger::flush_level() const {
|
||||
return static_cast<level::level_enum>(flush_level_.load(std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
// sinks
|
||||
SPDLOG_INLINE const std::vector<sink_ptr> &logger::sinks() const { return sinks_; }
|
||||
|
||||
SPDLOG_INLINE std::vector<sink_ptr> &logger::sinks() { return sinks_; }
|
||||
|
||||
// error handler
|
||||
SPDLOG_INLINE void logger::set_error_handler(err_handler handler) {
|
||||
custom_err_handler_ = std::move(handler);
|
||||
}
|
||||
|
||||
// create new logger with same sinks and configuration.
|
||||
SPDLOG_INLINE std::shared_ptr<logger> logger::clone(std::string logger_name) {
|
||||
auto cloned = std::make_shared<logger>(*this);
|
||||
cloned->name_ = std::move(logger_name);
|
||||
return cloned;
|
||||
}
|
||||
|
||||
// protected methods
|
||||
SPDLOG_INLINE void logger::log_it_(const spdlog::details::log_msg &log_msg,
|
||||
bool log_enabled,
|
||||
bool traceback_enabled) {
|
||||
if (log_enabled) {
|
||||
sink_it_(log_msg);
|
||||
}
|
||||
if (traceback_enabled) {
|
||||
tracer_.push_back(log_msg);
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void logger::sink_it_(const details::log_msg &msg) {
|
||||
for (auto &sink : sinks_) {
|
||||
if (sink->should_log(msg.level)) {
|
||||
SPDLOG_TRY { sink->log(msg); }
|
||||
SPDLOG_LOGGER_CATCH(msg.source)
|
||||
}
|
||||
}
|
||||
|
||||
if (should_flush_(msg)) {
|
||||
flush_();
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void logger::flush_() {
|
||||
for (auto &sink : sinks_) {
|
||||
SPDLOG_TRY { sink->flush(); }
|
||||
SPDLOG_LOGGER_CATCH(source_loc())
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void logger::dump_backtrace_() {
|
||||
using details::log_msg;
|
||||
if (tracer_.enabled() && !tracer_.empty()) {
|
||||
sink_it_(
|
||||
log_msg{name(), level::info, "****************** Backtrace Start ******************"});
|
||||
tracer_.foreach_pop([this](const log_msg &msg) { this->sink_it_(msg); });
|
||||
sink_it_(
|
||||
log_msg{name(), level::info, "****************** Backtrace End ********************"});
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE bool logger::should_flush_(const details::log_msg &msg) {
|
||||
auto flush_level = flush_level_.load(std::memory_order_relaxed);
|
||||
return (msg.level >= flush_level) && (msg.level != level::off);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void logger::err_handler_(const std::string &msg) {
|
||||
if (custom_err_handler_) {
|
||||
custom_err_handler_(msg);
|
||||
} else {
|
||||
using std::chrono::system_clock;
|
||||
static std::mutex mutex;
|
||||
static std::chrono::system_clock::time_point last_report_time;
|
||||
static size_t err_counter = 0;
|
||||
std::lock_guard<std::mutex> lk{mutex};
|
||||
auto now = system_clock::now();
|
||||
err_counter++;
|
||||
if (now - last_report_time < std::chrono::seconds(1)) {
|
||||
return;
|
||||
}
|
||||
last_report_time = now;
|
||||
auto tm_time = details::os::localtime(system_clock::to_time_t(now));
|
||||
char date_buf[64];
|
||||
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
|
||||
#if defined(USING_R) && defined(R_R_H) // if in R environment
|
||||
REprintf("[*** LOG ERROR #%04zu ***] [%s] [%s] %s\n", err_counter, date_buf, name().c_str(),
|
||||
msg.c_str());
|
||||
#else
|
||||
std::fprintf(stderr, "[*** LOG ERROR #%04zu ***] [%s] [%s] %s\n", err_counter, date_buf,
|
||||
name().c_str(), msg.c_str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // namespace spdlog
|
||||
379
third_party/spdlog_headers/spdlog/logger.h
vendored
Normal file
379
third_party/spdlog_headers/spdlog/logger.h
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
// Thread safe logger (except for set_error_handler())
|
||||
// Has name, log level, vector of std::shared sink pointers and formatter
|
||||
// Upon each log write the logger:
|
||||
// 1. Checks if its log level is enough to log the message and if yes:
|
||||
// 2. Call the underlying sinks to do the job.
|
||||
// 3. Each sink use its own private copy of a formatter to format the message
|
||||
// and send to its destination.
|
||||
//
|
||||
// The use of private formatter per sink provides the opportunity to cache some
|
||||
// formatted data, and support for different format per sink.
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/details/backtracer.h>
|
||||
#include <spdlog/details/log_msg.h>
|
||||
|
||||
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
#ifndef _WIN32
|
||||
#error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows
|
||||
#endif
|
||||
#include <spdlog/details/os.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifndef SPDLOG_NO_EXCEPTIONS
|
||||
#define SPDLOG_LOGGER_CATCH(location) \
|
||||
catch (const std::exception &ex) { \
|
||||
if (location.filename) { \
|
||||
err_handler_(fmt_lib::format(SPDLOG_FMT_STRING("{} [{}({})]"), ex.what(), \
|
||||
location.filename, location.line)); \
|
||||
} else { \
|
||||
err_handler_(ex.what()); \
|
||||
} \
|
||||
} \
|
||||
catch (...) { \
|
||||
err_handler_("Rethrowing unknown exception in logger"); \
|
||||
throw; \
|
||||
}
|
||||
#else
|
||||
#define SPDLOG_LOGGER_CATCH(location)
|
||||
#endif
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
class SPDLOG_API logger {
|
||||
public:
|
||||
// Empty logger
|
||||
explicit logger(std::string name)
|
||||
: name_(std::move(name)),
|
||||
sinks_() {}
|
||||
|
||||
// Logger with range on sinks
|
||||
template <typename It>
|
||||
logger(std::string name, It begin, It end)
|
||||
: name_(std::move(name)),
|
||||
sinks_(begin, end) {}
|
||||
|
||||
// Logger with single sink
|
||||
logger(std::string name, sink_ptr single_sink)
|
||||
: logger(std::move(name), {std::move(single_sink)}) {}
|
||||
|
||||
// Logger with sinks init list
|
||||
logger(std::string name, sinks_init_list sinks)
|
||||
: logger(std::move(name), sinks.begin(), sinks.end()) {}
|
||||
|
||||
virtual ~logger() = default;
|
||||
|
||||
logger(const logger &other);
|
||||
logger(logger &&other) SPDLOG_NOEXCEPT;
|
||||
logger &operator=(logger other) SPDLOG_NOEXCEPT;
|
||||
void swap(spdlog::logger &other) SPDLOG_NOEXCEPT;
|
||||
|
||||
template <typename... Args>
|
||||
void log(source_loc loc, level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) {
|
||||
log_(loc, lvl, details::to_string_view(fmt), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void log(level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void log(level::level_enum lvl, const T &msg) {
|
||||
log(source_loc{}, lvl, msg);
|
||||
}
|
||||
|
||||
// T cannot be statically converted to format string (including string_view/wstring_view)
|
||||
template <class T,
|
||||
typename std::enable_if<!is_convertible_to_any_format_string<const T &>::value,
|
||||
int>::type = 0>
|
||||
void log(source_loc loc, level::level_enum lvl, const T &msg) {
|
||||
log(loc, lvl, "{}", msg);
|
||||
}
|
||||
|
||||
void log(log_clock::time_point log_time,
|
||||
source_loc loc,
|
||||
level::level_enum lvl,
|
||||
string_view_t msg) {
|
||||
bool log_enabled = should_log(lvl);
|
||||
bool traceback_enabled = tracer_.enabled();
|
||||
if (!log_enabled && !traceback_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
details::log_msg log_msg(log_time, loc, name_, lvl, msg);
|
||||
log_it_(log_msg, log_enabled, traceback_enabled);
|
||||
}
|
||||
|
||||
void log(source_loc loc, level::level_enum lvl, string_view_t msg) {
|
||||
bool log_enabled = should_log(lvl);
|
||||
bool traceback_enabled = tracer_.enabled();
|
||||
if (!log_enabled && !traceback_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
details::log_msg log_msg(loc, name_, lvl, msg);
|
||||
log_it_(log_msg, log_enabled, traceback_enabled);
|
||||
}
|
||||
|
||||
void log(level::level_enum lvl, string_view_t msg) { log(source_loc{}, lvl, msg); }
|
||||
|
||||
template <typename... Args>
|
||||
void trace(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::trace, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void debug(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::debug, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void info(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::info, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void warn(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::warn, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void error(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::err, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void critical(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::critical, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
template <typename... Args>
|
||||
void log(source_loc loc, level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
log_(loc, lvl, details::to_string_view(fmt), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void log(level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void log(log_clock::time_point log_time,
|
||||
source_loc loc,
|
||||
level::level_enum lvl,
|
||||
wstring_view_t msg) {
|
||||
bool log_enabled = should_log(lvl);
|
||||
bool traceback_enabled = tracer_.enabled();
|
||||
if (!log_enabled && !traceback_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
memory_buf_t buf;
|
||||
details::os::wstr_to_utf8buf(wstring_view_t(msg.data(), msg.size()), buf);
|
||||
details::log_msg log_msg(log_time, loc, name_, lvl, string_view_t(buf.data(), buf.size()));
|
||||
log_it_(log_msg, log_enabled, traceback_enabled);
|
||||
}
|
||||
|
||||
void log(source_loc loc, level::level_enum lvl, wstring_view_t msg) {
|
||||
bool log_enabled = should_log(lvl);
|
||||
bool traceback_enabled = tracer_.enabled();
|
||||
if (!log_enabled && !traceback_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
memory_buf_t buf;
|
||||
details::os::wstr_to_utf8buf(wstring_view_t(msg.data(), msg.size()), buf);
|
||||
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
|
||||
log_it_(log_msg, log_enabled, traceback_enabled);
|
||||
}
|
||||
|
||||
void log(level::level_enum lvl, wstring_view_t msg) { log(source_loc{}, lvl, msg); }
|
||||
|
||||
template <typename... Args>
|
||||
void trace(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::trace, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void debug(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::debug, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void info(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::info, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void warn(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::warn, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void error(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::err, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void critical(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::critical, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
void trace(const T &msg) {
|
||||
log(level::trace, msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void debug(const T &msg) {
|
||||
log(level::debug, msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void info(const T &msg) {
|
||||
log(level::info, msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void warn(const T &msg) {
|
||||
log(level::warn, msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void error(const T &msg) {
|
||||
log(level::err, msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void critical(const T &msg) {
|
||||
log(level::critical, msg);
|
||||
}
|
||||
|
||||
// return true logging is enabled for the given level.
|
||||
bool should_log(level::level_enum msg_level) const {
|
||||
return msg_level >= level_.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
// return true if backtrace logging is enabled.
|
||||
bool should_backtrace() const { return tracer_.enabled(); }
|
||||
|
||||
void set_level(level::level_enum log_level);
|
||||
|
||||
level::level_enum level() const;
|
||||
|
||||
const std::string &name() const;
|
||||
|
||||
// set formatting for the sinks in this logger.
|
||||
// each sink will get a separate instance of the formatter object.
|
||||
void set_formatter(std::unique_ptr<formatter> f);
|
||||
|
||||
// set formatting for the sinks in this logger.
|
||||
// equivalent to
|
||||
// set_formatter(make_unique<pattern_formatter>(pattern, time_type))
|
||||
// Note: each sink will get a new instance of a formatter object, replacing the old one.
|
||||
void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
|
||||
|
||||
// backtrace support.
|
||||
// efficiently store all debug/trace messages in a circular buffer until needed for debugging.
|
||||
void enable_backtrace(size_t n_messages);
|
||||
void disable_backtrace();
|
||||
void dump_backtrace();
|
||||
|
||||
// flush functions
|
||||
void flush();
|
||||
void flush_on(level::level_enum log_level);
|
||||
level::level_enum flush_level() const;
|
||||
|
||||
// sinks
|
||||
const std::vector<sink_ptr> &sinks() const;
|
||||
|
||||
std::vector<sink_ptr> &sinks();
|
||||
|
||||
// error handler
|
||||
void set_error_handler(err_handler);
|
||||
|
||||
// create new logger with same sinks and configuration.
|
||||
virtual std::shared_ptr<logger> clone(std::string logger_name);
|
||||
|
||||
protected:
|
||||
std::string name_;
|
||||
std::vector<sink_ptr> sinks_;
|
||||
spdlog::level_t level_{level::info};
|
||||
spdlog::level_t flush_level_{level::off};
|
||||
err_handler custom_err_handler_{nullptr};
|
||||
details::backtracer tracer_;
|
||||
|
||||
// common implementation for after templated public api has been resolved
|
||||
template <typename... Args>
|
||||
void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&...args) {
|
||||
bool log_enabled = should_log(lvl);
|
||||
bool traceback_enabled = tracer_.enabled();
|
||||
if (!log_enabled && !traceback_enabled) {
|
||||
return;
|
||||
}
|
||||
SPDLOG_TRY {
|
||||
memory_buf_t buf;
|
||||
#ifdef SPDLOG_USE_STD_FORMAT
|
||||
fmt_lib::vformat_to(std::back_inserter(buf), fmt, fmt_lib::make_format_args(args...));
|
||||
#else
|
||||
fmt::vformat_to(fmt::appender(buf), fmt, fmt::make_format_args(args...));
|
||||
#endif
|
||||
|
||||
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
|
||||
log_it_(log_msg, log_enabled, traceback_enabled);
|
||||
}
|
||||
SPDLOG_LOGGER_CATCH(loc)
|
||||
}
|
||||
|
||||
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
template <typename... Args>
|
||||
void log_(source_loc loc, level::level_enum lvl, wstring_view_t fmt, Args &&...args) {
|
||||
bool log_enabled = should_log(lvl);
|
||||
bool traceback_enabled = tracer_.enabled();
|
||||
if (!log_enabled && !traceback_enabled) {
|
||||
return;
|
||||
}
|
||||
SPDLOG_TRY {
|
||||
// format to wmemory_buffer and convert to utf8
|
||||
wmemory_buf_t wbuf;
|
||||
fmt_lib::vformat_to(std::back_inserter(wbuf), fmt,
|
||||
fmt_lib::make_format_args<fmt_lib::wformat_context>(args...));
|
||||
|
||||
memory_buf_t buf;
|
||||
details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf);
|
||||
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
|
||||
log_it_(log_msg, log_enabled, traceback_enabled);
|
||||
}
|
||||
SPDLOG_LOGGER_CATCH(loc)
|
||||
}
|
||||
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
|
||||
// log the given message (if the given log level is high enough),
|
||||
// and save backtrace (if backtrace is enabled).
|
||||
void log_it_(const details::log_msg &log_msg, bool log_enabled, bool traceback_enabled);
|
||||
virtual void sink_it_(const details::log_msg &msg);
|
||||
virtual void flush_();
|
||||
void dump_backtrace_();
|
||||
bool should_flush_(const details::log_msg &msg);
|
||||
|
||||
// handle errors during logging.
|
||||
// default handler prints the error to stderr at max rate of 1 message/sec.
|
||||
void err_handler_(const std::string &msg);
|
||||
};
|
||||
|
||||
void swap(logger &a, logger &b);
|
||||
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "logger-inl.h"
|
||||
#endif
|
||||
1268
third_party/spdlog_headers/spdlog/pattern_formatter-inl.h
vendored
Normal file
1268
third_party/spdlog_headers/spdlog/pattern_formatter-inl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
118
third_party/spdlog_headers/spdlog/pattern_formatter.h
vendored
Normal file
118
third_party/spdlog_headers/spdlog/pattern_formatter.h
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/details/log_msg.h>
|
||||
#include <spdlog/details/os.h>
|
||||
#include <spdlog/formatter.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
// padding information.
|
||||
struct padding_info {
|
||||
enum class pad_side { left, right, center };
|
||||
|
||||
padding_info() = default;
|
||||
padding_info(size_t width, padding_info::pad_side side, bool truncate)
|
||||
: width_(width),
|
||||
side_(side),
|
||||
truncate_(truncate),
|
||||
enabled_(true) {}
|
||||
|
||||
bool enabled() const { return enabled_; }
|
||||
size_t width_ = 0;
|
||||
pad_side side_ = pad_side::left;
|
||||
bool truncate_ = false;
|
||||
bool enabled_ = false;
|
||||
};
|
||||
|
||||
class SPDLOG_API flag_formatter {
|
||||
public:
|
||||
explicit flag_formatter(padding_info padinfo)
|
||||
: padinfo_(padinfo) {}
|
||||
flag_formatter() = default;
|
||||
virtual ~flag_formatter() = default;
|
||||
virtual void format(const details::log_msg &msg,
|
||||
const std::tm &tm_time,
|
||||
memory_buf_t &dest) = 0;
|
||||
|
||||
protected:
|
||||
padding_info padinfo_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
class SPDLOG_API custom_flag_formatter : public details::flag_formatter {
|
||||
public:
|
||||
virtual std::unique_ptr<custom_flag_formatter> clone() const = 0;
|
||||
|
||||
void set_padding_info(const 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 = custom_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);
|
||||
|
||||
pattern_formatter(const pattern_formatter &other) = delete;
|
||||
pattern_formatter &operator=(const pattern_formatter &other) = delete;
|
||||
|
||||
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, Args &&...args) {
|
||||
custom_handlers_[flag] = details::make_unique<T>(std::forward<Args>(args)...);
|
||||
return *this;
|
||||
}
|
||||
void set_pattern(std::string pattern);
|
||||
void need_localtime(bool need = true);
|
||||
|
||||
private:
|
||||
std::string pattern_;
|
||||
std::string eol_;
|
||||
pattern_time_type pattern_time_type_;
|
||||
bool need_localtime_;
|
||||
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>
|
||||
void handle_flag_(char flag, details::padding_info padding);
|
||||
|
||||
// Extract given pad spec (e.g. %8X)
|
||||
// Advance the given it pass the end of the padding spec found (if any)
|
||||
// Return padding.
|
||||
static details::padding_info handle_padspec_(std::string::const_iterator &it,
|
||||
std::string::const_iterator end);
|
||||
|
||||
void compile_pattern_(const std::string &pattern);
|
||||
};
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "pattern_formatter-inl.h"
|
||||
#endif
|
||||
135
third_party/spdlog_headers/spdlog/sinks/ansicolor_sink-inl.h
vendored
Normal file
135
third_party/spdlog_headers/spdlog/sinks/ansicolor_sink-inl.h
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
// 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/sinks/ansicolor_sink.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/details/os.h>
|
||||
#include <spdlog/pattern_formatter.h>
|
||||
|
||||
namespace spdlog {
|
||||
namespace sinks {
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE ansicolor_sink<ConsoleMutex>::ansicolor_sink(FILE *target_file, color_mode mode)
|
||||
: target_file_(target_file),
|
||||
mutex_(ConsoleMutex::mutex()),
|
||||
formatter_(details::make_unique<spdlog::pattern_formatter>())
|
||||
|
||||
{
|
||||
set_color_mode(mode);
|
||||
colors_.at(level::trace) = to_string_(white);
|
||||
colors_.at(level::debug) = to_string_(cyan);
|
||||
colors_.at(level::info) = to_string_(green);
|
||||
colors_.at(level::warn) = to_string_(yellow_bold);
|
||||
colors_.at(level::err) = to_string_(red_bold);
|
||||
colors_.at(level::critical) = to_string_(bold_on_red);
|
||||
colors_.at(level::off) = to_string_(reset);
|
||||
}
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_color(level::level_enum color_level,
|
||||
string_view_t color) {
|
||||
std::lock_guard<mutex_t> lock(mutex_);
|
||||
colors_.at(static_cast<size_t>(color_level)) = to_string_(color);
|
||||
}
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
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) {
|
||||
// before color range
|
||||
print_range_(formatted, 0, msg.color_range_start);
|
||||
// in color range
|
||||
print_ccode_(colors_.at(static_cast<size_t>(msg.level)));
|
||||
print_range_(formatted, msg.color_range_start, msg.color_range_end);
|
||||
print_ccode_(reset);
|
||||
// after color range
|
||||
print_range_(formatted, msg.color_range_end, formatted.size());
|
||||
} else // no color
|
||||
{
|
||||
print_range_(formatted, 0, formatted.size());
|
||||
}
|
||||
fflush(target_file_);
|
||||
}
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::flush() {
|
||||
std::lock_guard<mutex_t> lock(mutex_);
|
||||
fflush(target_file_);
|
||||
}
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_pattern(const std::string &pattern) {
|
||||
std::lock_guard<mutex_t> lock(mutex_);
|
||||
formatter_ = std::unique_ptr<spdlog::formatter>(new pattern_formatter(pattern));
|
||||
}
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_formatter(
|
||||
std::unique_ptr<spdlog::formatter> sink_formatter) {
|
||||
std::lock_guard<mutex_t> lock(mutex_);
|
||||
formatter_ = std::move(sink_formatter);
|
||||
}
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE bool ansicolor_sink<ConsoleMutex>::should_color() {
|
||||
return should_do_colors_;
|
||||
}
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_color_mode(color_mode mode) {
|
||||
switch (mode) {
|
||||
case color_mode::always:
|
||||
should_do_colors_ = true;
|
||||
return;
|
||||
case color_mode::automatic:
|
||||
should_do_colors_ =
|
||||
details::os::in_terminal(target_file_) && details::os::is_color_terminal();
|
||||
return;
|
||||
case color_mode::never:
|
||||
should_do_colors_ = false;
|
||||
return;
|
||||
default:
|
||||
should_do_colors_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::print_ccode_(const string_view_t &color_code) {
|
||||
fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_);
|
||||
}
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::print_range_(const memory_buf_t &formatted,
|
||||
size_t start,
|
||||
size_t end) {
|
||||
fwrite(formatted.data() + start, sizeof(char), end - start, target_file_);
|
||||
}
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE std::string ansicolor_sink<ConsoleMutex>::to_string_(const string_view_t &sv) {
|
||||
return std::string(sv.data(), sv.size());
|
||||
}
|
||||
|
||||
// ansicolor_stdout_sink
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE ansicolor_stdout_sink<ConsoleMutex>::ansicolor_stdout_sink(color_mode mode)
|
||||
: ansicolor_sink<ConsoleMutex>(stdout, mode) {}
|
||||
|
||||
// ansicolor_stderr_sink
|
||||
template <typename ConsoleMutex>
|
||||
SPDLOG_INLINE ansicolor_stderr_sink<ConsoleMutex>::ansicolor_stderr_sink(color_mode mode)
|
||||
: ansicolor_sink<ConsoleMutex>(stderr, mode) {}
|
||||
|
||||
} // namespace sinks
|
||||
} // namespace spdlog
|
||||
115
third_party/spdlog_headers/spdlog/sinks/ansicolor_sink.h
vendored
Normal file
115
third_party/spdlog_headers/spdlog/sinks/ansicolor_sink.h
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <spdlog/details/console_globals.h>
|
||||
#include <spdlog/details/null_mutex.h>
|
||||
#include <spdlog/sinks/sink.h>
|
||||
#include <string>
|
||||
|
||||
namespace spdlog {
|
||||
namespace sinks {
|
||||
|
||||
/**
|
||||
* This sink prefixes the output with an ANSI escape sequence color code
|
||||
* depending on the severity
|
||||
* of the message.
|
||||
* If no color terminal detected, omit the escape codes.
|
||||
*/
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
class ansicolor_sink : public sink {
|
||||
public:
|
||||
using mutex_t = typename ConsoleMutex::mutex_t;
|
||||
ansicolor_sink(FILE *target_file, color_mode mode);
|
||||
~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();
|
||||
|
||||
void log(const details::log_msg &msg) override;
|
||||
void flush() override;
|
||||
void set_pattern(const std::string &pattern) final;
|
||||
void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) override;
|
||||
|
||||
// Formatting codes
|
||||
const string_view_t reset = "\033[m";
|
||||
const string_view_t bold = "\033[1m";
|
||||
const string_view_t dark = "\033[2m";
|
||||
const string_view_t underline = "\033[4m";
|
||||
const string_view_t blink = "\033[5m";
|
||||
const string_view_t reverse = "\033[7m";
|
||||
const string_view_t concealed = "\033[8m";
|
||||
const string_view_t clear_line = "\033[K";
|
||||
|
||||
// Foreground colors
|
||||
const string_view_t black = "\033[30m";
|
||||
const string_view_t red = "\033[31m";
|
||||
const string_view_t green = "\033[32m";
|
||||
const string_view_t yellow = "\033[33m";
|
||||
const string_view_t blue = "\033[34m";
|
||||
const string_view_t magenta = "\033[35m";
|
||||
const string_view_t cyan = "\033[36m";
|
||||
const string_view_t white = "\033[37m";
|
||||
|
||||
/// Background colors
|
||||
const string_view_t on_black = "\033[40m";
|
||||
const string_view_t on_red = "\033[41m";
|
||||
const string_view_t on_green = "\033[42m";
|
||||
const string_view_t on_yellow = "\033[43m";
|
||||
const string_view_t on_blue = "\033[44m";
|
||||
const string_view_t on_magenta = "\033[45m";
|
||||
const string_view_t on_cyan = "\033[46m";
|
||||
const string_view_t on_white = "\033[47m";
|
||||
|
||||
/// Bold colors
|
||||
const string_view_t yellow_bold = "\033[33m\033[1m";
|
||||
const string_view_t red_bold = "\033[31m\033[1m";
|
||||
const string_view_t bold_on_red = "\033[1m\033[41m";
|
||||
|
||||
private:
|
||||
FILE *target_file_;
|
||||
mutex_t &mutex_;
|
||||
bool should_do_colors_;
|
||||
std::unique_ptr<spdlog::formatter> formatter_;
|
||||
std::array<std::string, level::n_levels> colors_;
|
||||
void print_ccode_(const string_view_t &color_code);
|
||||
void print_range_(const memory_buf_t &formatted, size_t start, size_t end);
|
||||
static std::string to_string_(const string_view_t &sv);
|
||||
};
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
class ansicolor_stdout_sink : public ansicolor_sink<ConsoleMutex> {
|
||||
public:
|
||||
explicit ansicolor_stdout_sink(color_mode mode = color_mode::automatic);
|
||||
};
|
||||
|
||||
template <typename ConsoleMutex>
|
||||
class ansicolor_stderr_sink : public ansicolor_sink<ConsoleMutex> {
|
||||
public:
|
||||
explicit ansicolor_stderr_sink(color_mode mode = color_mode::automatic);
|
||||
};
|
||||
|
||||
using ansicolor_stdout_sink_mt = ansicolor_stdout_sink<details::console_mutex>;
|
||||
using ansicolor_stdout_sink_st = ansicolor_stdout_sink<details::console_nullmutex>;
|
||||
|
||||
using ansicolor_stderr_sink_mt = ansicolor_stderr_sink<details::console_mutex>;
|
||||
using ansicolor_stderr_sink_st = ansicolor_stderr_sink<details::console_nullmutex>;
|
||||
|
||||
} // namespace sinks
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "ansicolor_sink-inl.h"
|
||||
#endif
|
||||
59
third_party/spdlog_headers/spdlog/sinks/base_sink-inl.h
vendored
Normal file
59
third_party/spdlog_headers/spdlog/sinks/base_sink-inl.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// 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/sinks/base_sink.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/pattern_formatter.h>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
template <typename Mutex>
|
||||
SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::base_sink()
|
||||
: formatter_{details::make_unique<spdlog::pattern_formatter>()} {}
|
||||
|
||||
template <typename Mutex>
|
||||
SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::base_sink(
|
||||
std::unique_ptr<spdlog::formatter> formatter)
|
||||
: formatter_{std::move(formatter)} {}
|
||||
|
||||
template <typename Mutex>
|
||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::log(const details::log_msg &msg) {
|
||||
std::lock_guard<Mutex> lock(mutex_);
|
||||
sink_it_(msg);
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::flush() {
|
||||
std::lock_guard<Mutex> lock(mutex_);
|
||||
flush_();
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::set_pattern(const std::string &pattern) {
|
||||
std::lock_guard<Mutex> lock(mutex_);
|
||||
set_pattern_(pattern);
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
void SPDLOG_INLINE
|
||||
spdlog::sinks::base_sink<Mutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
||||
std::lock_guard<Mutex> lock(mutex_);
|
||||
set_formatter_(std::move(sink_formatter));
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::set_pattern_(const std::string &pattern) {
|
||||
set_formatter_(details::make_unique<spdlog::pattern_formatter>(pattern));
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
void SPDLOG_INLINE
|
||||
spdlog::sinks::base_sink<Mutex>::set_formatter_(std::unique_ptr<spdlog::formatter> sink_formatter) {
|
||||
formatter_ = std::move(sink_formatter);
|
||||
}
|
||||
51
third_party/spdlog_headers/spdlog/sinks/base_sink.h
vendored
Normal file
51
third_party/spdlog_headers/spdlog/sinks/base_sink.h
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
//
|
||||
// base sink templated over a mutex (either dummy or real)
|
||||
// concrete implementation should override the sink_it_() and flush_() methods.
|
||||
// locking is taken care of in this class - no locking needed by the
|
||||
// implementers..
|
||||
//
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/details/log_msg.h>
|
||||
#include <spdlog/sinks/sink.h>
|
||||
|
||||
namespace spdlog {
|
||||
namespace sinks {
|
||||
template <typename Mutex>
|
||||
class SPDLOG_API 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;
|
||||
void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) final;
|
||||
|
||||
protected:
|
||||
// sink formatter
|
||||
std::unique_ptr<spdlog::formatter> formatter_;
|
||||
Mutex mutex_;
|
||||
|
||||
virtual void sink_it_(const details::log_msg &msg) = 0;
|
||||
virtual void flush_() = 0;
|
||||
virtual void set_pattern_(const std::string &pattern);
|
||||
virtual void set_formatter_(std::unique_ptr<spdlog::formatter> sink_formatter);
|
||||
};
|
||||
} // namespace sinks
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "base_sink-inl.h"
|
||||
#endif
|
||||
42
third_party/spdlog_headers/spdlog/sinks/basic_file_sink-inl.h
vendored
Normal file
42
third_party/spdlog_headers/spdlog/sinks/basic_file_sink-inl.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// 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/sinks/basic_file_sink.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/details/os.h>
|
||||
|
||||
namespace spdlog {
|
||||
namespace sinks {
|
||||
|
||||
template <typename Mutex>
|
||||
SPDLOG_INLINE basic_file_sink<Mutex>::basic_file_sink(const filename_t &filename,
|
||||
bool truncate,
|
||||
const file_event_handlers &event_handlers)
|
||||
: file_helper_{event_handlers} {
|
||||
file_helper_.open(filename, truncate);
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
SPDLOG_INLINE const filename_t &basic_file_sink<Mutex>::filename() const {
|
||||
return file_helper_.filename();
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
SPDLOG_INLINE void basic_file_sink<Mutex>::sink_it_(const details::log_msg &msg) {
|
||||
memory_buf_t formatted;
|
||||
base_sink<Mutex>::formatter_->format(msg, formatted);
|
||||
file_helper_.write(formatted);
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
SPDLOG_INLINE void basic_file_sink<Mutex>::flush_() {
|
||||
file_helper_.flush();
|
||||
}
|
||||
|
||||
} // namespace sinks
|
||||
} // namespace spdlog
|
||||
65
third_party/spdlog_headers/spdlog/sinks/basic_file_sink.h
vendored
Normal file
65
third_party/spdlog_headers/spdlog/sinks/basic_file_sink.h
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/details/file_helper.h>
|
||||
#include <spdlog/details/null_mutex.h>
|
||||
#include <spdlog/details/synchronous_factory.h>
|
||||
#include <spdlog/sinks/base_sink.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace spdlog {
|
||||
namespace sinks {
|
||||
/*
|
||||
* Trivial file sink with single file as target
|
||||
*/
|
||||
template <typename Mutex>
|
||||
class basic_file_sink final : public base_sink<Mutex> {
|
||||
public:
|
||||
explicit basic_file_sink(const filename_t &filename,
|
||||
bool truncate = false,
|
||||
const file_event_handlers &event_handlers = {});
|
||||
const filename_t &filename() const;
|
||||
|
||||
protected:
|
||||
void sink_it_(const details::log_msg &msg) override;
|
||||
void flush_() override;
|
||||
|
||||
private:
|
||||
details::file_helper file_helper_;
|
||||
};
|
||||
|
||||
using basic_file_sink_mt = basic_file_sink<std::mutex>;
|
||||
using basic_file_sink_st = basic_file_sink<details::null_mutex>;
|
||||
|
||||
} // namespace sinks
|
||||
|
||||
//
|
||||
// factory functions
|
||||
//
|
||||
template <typename Factory = spdlog::synchronous_factory>
|
||||
inline std::shared_ptr<logger> basic_logger_mt(const std::string &logger_name,
|
||||
const filename_t &filename,
|
||||
bool truncate = false,
|
||||
const file_event_handlers &event_handlers = {}) {
|
||||
return Factory::template create<sinks::basic_file_sink_mt>(logger_name, filename, truncate,
|
||||
event_handlers);
|
||||
}
|
||||
|
||||
template <typename Factory = spdlog::synchronous_factory>
|
||||
inline std::shared_ptr<logger> basic_logger_st(const std::string &logger_name,
|
||||
const filename_t &filename,
|
||||
bool truncate = false,
|
||||
const file_event_handlers &event_handlers = {}) {
|
||||
return Factory::template create<sinks::basic_file_sink_st>(logger_name, filename, truncate,
|
||||
event_handlers);
|
||||
}
|
||||
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "basic_file_sink-inl.h"
|
||||
#endif
|
||||
22
third_party/spdlog_headers/spdlog/sinks/sink-inl.h
vendored
Normal file
22
third_party/spdlog_headers/spdlog/sinks/sink-inl.h
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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/sinks/sink.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/common.h>
|
||||
|
||||
SPDLOG_INLINE bool spdlog::sinks::sink::should_log(spdlog::level::level_enum msg_level) const {
|
||||
return msg_level >= level_.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void spdlog::sinks::sink::set_level(level::level_enum log_level) {
|
||||
level_.store(log_level, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE spdlog::level::level_enum spdlog::sinks::sink::level() const {
|
||||
return static_cast<spdlog::level::level_enum>(level_.load(std::memory_order_relaxed));
|
||||
}
|
||||
34
third_party/spdlog_headers/spdlog/sinks/sink.h
vendored
Normal file
34
third_party/spdlog_headers/spdlog/sinks/sink.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/details/log_msg.h>
|
||||
#include <spdlog/formatter.h>
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
namespace sinks {
|
||||
class SPDLOG_API sink {
|
||||
public:
|
||||
virtual ~sink() = default;
|
||||
virtual void log(const details::log_msg &msg) = 0;
|
||||
virtual void flush() = 0;
|
||||
virtual void set_pattern(const std::string &pattern) = 0;
|
||||
virtual void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) = 0;
|
||||
|
||||
void set_level(level::level_enum log_level);
|
||||
level::level_enum level() const;
|
||||
bool should_log(level::level_enum msg_level) const;
|
||||
|
||||
protected:
|
||||
// sink log level - default is all
|
||||
level_t level_{level::trace};
|
||||
};
|
||||
|
||||
} // namespace sinks
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "sink-inl.h"
|
||||
#endif
|
||||
102
third_party/spdlog_headers/spdlog/spdlog-inl.h
vendored
Normal file
102
third_party/spdlog_headers/spdlog/spdlog-inl.h
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
// 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/spdlog.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/pattern_formatter.h>
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
SPDLOG_INLINE void initialize_logger(std::shared_ptr<logger> logger) {
|
||||
details::registry::instance().initialize_logger(std::move(logger));
|
||||
}
|
||||
|
||||
SPDLOG_INLINE std::shared_ptr<logger> get(const std::string &name) {
|
||||
return details::registry::instance().get(name);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201703L // C++17
|
||||
SPDLOG_INLINE std::shared_ptr<logger> get(std::string_view name) {
|
||||
return details::registry::instance().get(name);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE std::shared_ptr<logger> get(const char *name) {
|
||||
return details::registry::instance().get(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
SPDLOG_INLINE void set_formatter(std::unique_ptr<spdlog::formatter> formatter) {
|
||||
details::registry::instance().set_formatter(std::move(formatter));
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void set_pattern(std::string pattern, pattern_time_type time_type) {
|
||||
set_formatter(
|
||||
std::unique_ptr<spdlog::formatter>(new pattern_formatter(std::move(pattern), time_type)));
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void enable_backtrace(size_t n_messages) {
|
||||
details::registry::instance().enable_backtrace(n_messages);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void disable_backtrace() { details::registry::instance().disable_backtrace(); }
|
||||
|
||||
SPDLOG_INLINE void dump_backtrace() { default_logger_raw()->dump_backtrace(); }
|
||||
|
||||
SPDLOG_INLINE level::level_enum get_level() { return default_logger_raw()->level(); }
|
||||
|
||||
SPDLOG_INLINE bool should_log(level::level_enum log_level) {
|
||||
return default_logger_raw()->should_log(log_level);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void set_level(level::level_enum log_level) {
|
||||
details::registry::instance().set_level(log_level);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void flush_on(level::level_enum log_level) {
|
||||
details::registry::instance().flush_on(log_level);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void set_error_handler(void (*handler)(const std::string &msg)) {
|
||||
details::registry::instance().set_error_handler(handler);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void register_logger(std::shared_ptr<logger> logger) {
|
||||
details::registry::instance().register_logger(std::move(logger));
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun) {
|
||||
details::registry::instance().apply_all(fun);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void drop(const std::string &name) { details::registry::instance().drop(name); }
|
||||
|
||||
SPDLOG_INLINE void drop_all() { details::registry::instance().drop_all(); }
|
||||
|
||||
SPDLOG_INLINE void shutdown() { details::registry::instance().shutdown(); }
|
||||
|
||||
SPDLOG_INLINE void set_automatic_registration(bool automatic_registration) {
|
||||
details::registry::instance().set_automatic_registration(automatic_registration);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE std::shared_ptr<spdlog::logger> default_logger() {
|
||||
return details::registry::instance().default_logger();
|
||||
}
|
||||
|
||||
SPDLOG_INLINE spdlog::logger *default_logger_raw() {
|
||||
return details::registry::instance().get_default_raw();
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void set_default_logger(std::shared_ptr<spdlog::logger> default_logger) {
|
||||
details::registry::instance().set_default_logger(std::move(default_logger));
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void apply_logger_env_levels(std::shared_ptr<logger> logger) {
|
||||
details::registry::instance().apply_logger_env_levels(std::move(logger));
|
||||
}
|
||||
|
||||
} // namespace spdlog
|
||||
360
third_party/spdlog_headers/spdlog/spdlog.h
vendored
Normal file
360
third_party/spdlog_headers/spdlog/spdlog.h
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
// spdlog main header file.
|
||||
// see example.cpp for usage example
|
||||
|
||||
#ifndef SPDLOG_H
|
||||
#define SPDLOG_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/details/registry.h>
|
||||
#include <spdlog/details/synchronous_factory.h>
|
||||
#include <spdlog/logger.h>
|
||||
#include <spdlog/version.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#if __cplusplus >= 201703L // C++17
|
||||
#include <string_view>
|
||||
#endif
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
using default_factory = synchronous_factory;
|
||||
|
||||
// Create and register a logger with a templated sink type
|
||||
// The logger's level, formatter and flush level will be set according the
|
||||
// global settings.
|
||||
//
|
||||
// Example:
|
||||
// spdlog::create<daily_file_sink_st>("logger_name", "dailylog_filename", 11, 59);
|
||||
template <typename Sink, typename... SinkArgs>
|
||||
inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&...sink_args) {
|
||||
return default_factory::create<Sink>(std::move(logger_name),
|
||||
std::forward<SinkArgs>(sink_args)...);
|
||||
}
|
||||
|
||||
// Initialize and register a logger,
|
||||
// formatter and flush level will be set according the global settings.
|
||||
//
|
||||
// Useful for initializing manually created loggers with the global settings.
|
||||
//
|
||||
// Example:
|
||||
// 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");
|
||||
SPDLOG_API std::shared_ptr<logger> get(const std::string &name);
|
||||
#if __cplusplus >= 201703L // C++17
|
||||
SPDLOG_API std::shared_ptr<logger> get(std::string_view name);
|
||||
SPDLOG_API std::shared_ptr<logger> get(const char *name);
|
||||
#endif
|
||||
|
||||
// Set global formatter. Each sink in each logger will get a clone of this object
|
||||
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");
|
||||
SPDLOG_API void set_pattern(std::string pattern,
|
||||
pattern_time_type time_type = pattern_time_type::local);
|
||||
|
||||
// enable global backtrace support
|
||||
SPDLOG_API void enable_backtrace(size_t n_messages);
|
||||
|
||||
// disable global backtrace support
|
||||
SPDLOG_API void disable_backtrace();
|
||||
|
||||
// call dump backtrace on default logger
|
||||
SPDLOG_API void dump_backtrace();
|
||||
|
||||
// Get global logging level
|
||||
SPDLOG_API level::level_enum get_level();
|
||||
|
||||
// Set global logging level
|
||||
SPDLOG_API void set_level(level::level_enum log_level);
|
||||
|
||||
// Determine whether the default logger should log messages with a certain level
|
||||
SPDLOG_API bool should_log(level::level_enum lvl);
|
||||
|
||||
// Set global flush 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!
|
||||
template <typename Rep, typename Period>
|
||||
inline void flush_every(std::chrono::duration<Rep, Period> interval) {
|
||||
details::registry::instance().flush_every(interval);
|
||||
}
|
||||
|
||||
// Set global error handler
|
||||
SPDLOG_API void set_error_handler(void (*handler)(const std::string &msg));
|
||||
|
||||
// Register the given logger with the given name
|
||||
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();});
|
||||
SPDLOG_API void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun);
|
||||
|
||||
// Drop the reference to the given logger
|
||||
SPDLOG_API void drop(const std::string &name);
|
||||
|
||||
// Drop all references from the registry
|
||||
SPDLOG_API void drop_all();
|
||||
|
||||
// stop any running threads started by spdlog and clean registry loggers
|
||||
SPDLOG_API void shutdown();
|
||||
|
||||
// Automatic registration of loggers when using spdlog::create() or spdlog::create_async
|
||||
SPDLOG_API void set_automatic_registration(bool automatic_registration);
|
||||
|
||||
// API for using default logger (stdout_color_mt),
|
||||
// e.g: spdlog::info("Message {}", 1);
|
||||
//
|
||||
// The default logger object can be accessed using the spdlog::default_logger():
|
||||
// For example, to add another sink to it:
|
||||
// spdlog::default_logger()->sinks().push_back(some_sink);
|
||||
//
|
||||
// The default logger can replaced using spdlog::set_default_logger(new_logger).
|
||||
// For example, to replace it with a file logger.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// The default API is thread safe (for _mt loggers), but:
|
||||
// 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.
|
||||
|
||||
SPDLOG_API std::shared_ptr<spdlog::logger> default_logger();
|
||||
|
||||
SPDLOG_API spdlog::logger *default_logger_raw();
|
||||
|
||||
SPDLOG_API void set_default_logger(std::shared_ptr<spdlog::logger> default_logger);
|
||||
|
||||
// Initialize logger level based on environment configs.
|
||||
//
|
||||
// Useful for applying SPDLOG_LEVEL to manually created loggers.
|
||||
//
|
||||
// Example:
|
||||
// auto mylogger = std::make_shared<spdlog::logger>("mylogger", ...);
|
||||
// spdlog::apply_logger_env_levels(mylogger);
|
||||
SPDLOG_API void apply_logger_env_levels(std::shared_ptr<logger> logger);
|
||||
|
||||
template <typename... Args>
|
||||
inline void log(source_loc source,
|
||||
level::level_enum lvl,
|
||||
format_string_t<Args...> fmt,
|
||||
Args &&...args) {
|
||||
default_logger_raw()->log(source, lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void log(level::level_enum lvl, format_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void trace(format_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->trace(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void debug(format_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->debug(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void info(format_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->info(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void warn(format_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->warn(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void error(format_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->error(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void critical(format_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->critical(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void log(source_loc source, level::level_enum lvl, const T &msg) {
|
||||
default_logger_raw()->log(source, lvl, msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void log(level::level_enum lvl, const T &msg) {
|
||||
default_logger_raw()->log(lvl, msg);
|
||||
}
|
||||
|
||||
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
template <typename... Args>
|
||||
inline void log(source_loc source,
|
||||
level::level_enum lvl,
|
||||
wformat_string_t<Args...> fmt,
|
||||
Args &&...args) {
|
||||
default_logger_raw()->log(source, lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void log(level::level_enum lvl, wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->log(source_loc{}, lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void trace(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->trace(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void debug(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->debug(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void info(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->info(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void warn(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->warn(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void error(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->error(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void critical(wformat_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->critical(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline void trace(const T &msg) {
|
||||
default_logger_raw()->trace(msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void debug(const T &msg) {
|
||||
default_logger_raw()->debug(msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void info(const T &msg) {
|
||||
default_logger_raw()->info(msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void warn(const T &msg) {
|
||||
default_logger_raw()->warn(msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void error(const T &msg) {
|
||||
default_logger_raw()->error(msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void critical(const T &msg) {
|
||||
default_logger_raw()->critical(msg);
|
||||
}
|
||||
|
||||
} // namespace spdlog
|
||||
|
||||
//
|
||||
// enable/disable log calls at compile time according to global level.
|
||||
//
|
||||
// define SPDLOG_ACTIVE_LEVEL to one of those (before including spdlog.h):
|
||||
// SPDLOG_LEVEL_TRACE,
|
||||
// SPDLOG_LEVEL_DEBUG,
|
||||
// SPDLOG_LEVEL_INFO,
|
||||
// SPDLOG_LEVEL_WARN,
|
||||
// SPDLOG_LEVEL_ERROR,
|
||||
// SPDLOG_LEVEL_CRITICAL,
|
||||
// SPDLOG_LEVEL_OFF
|
||||
//
|
||||
|
||||
#ifndef SPDLOG_NO_SOURCE_LOC
|
||||
#define SPDLOG_LOGGER_CALL(logger, level, ...) \
|
||||
(logger)->log(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_CALL(logger, level, ...) \
|
||||
(logger)->log(spdlog::source_loc{}, level, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
|
||||
#define SPDLOG_LOGGER_TRACE(logger, ...) \
|
||||
SPDLOG_LOGGER_CALL(logger, spdlog::level::trace, __VA_ARGS__)
|
||||
#define SPDLOG_TRACE(...) SPDLOG_LOGGER_TRACE(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_TRACE(logger, ...) (void)0
|
||||
#define SPDLOG_TRACE(...) (void)0
|
||||
#endif
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
|
||||
#define SPDLOG_LOGGER_DEBUG(logger, ...) \
|
||||
SPDLOG_LOGGER_CALL(logger, spdlog::level::debug, __VA_ARGS__)
|
||||
#define SPDLOG_DEBUG(...) SPDLOG_LOGGER_DEBUG(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_DEBUG(logger, ...) (void)0
|
||||
#define SPDLOG_DEBUG(...) (void)0
|
||||
#endif
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_INFO
|
||||
#define SPDLOG_LOGGER_INFO(logger, ...) \
|
||||
SPDLOG_LOGGER_CALL(logger, spdlog::level::info, __VA_ARGS__)
|
||||
#define SPDLOG_INFO(...) SPDLOG_LOGGER_INFO(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_INFO(logger, ...) (void)0
|
||||
#define SPDLOG_INFO(...) (void)0
|
||||
#endif
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_WARN
|
||||
#define SPDLOG_LOGGER_WARN(logger, ...) \
|
||||
SPDLOG_LOGGER_CALL(logger, spdlog::level::warn, __VA_ARGS__)
|
||||
#define SPDLOG_WARN(...) SPDLOG_LOGGER_WARN(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_WARN(logger, ...) (void)0
|
||||
#define SPDLOG_WARN(...) (void)0
|
||||
#endif
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_ERROR
|
||||
#define SPDLOG_LOGGER_ERROR(logger, ...) \
|
||||
SPDLOG_LOGGER_CALL(logger, spdlog::level::err, __VA_ARGS__)
|
||||
#define SPDLOG_ERROR(...) SPDLOG_LOGGER_ERROR(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_ERROR(logger, ...) (void)0
|
||||
#define SPDLOG_ERROR(...) (void)0
|
||||
#endif
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_CRITICAL
|
||||
#define SPDLOG_LOGGER_CRITICAL(logger, ...) \
|
||||
SPDLOG_LOGGER_CALL(logger, spdlog::level::critical, __VA_ARGS__)
|
||||
#define SPDLOG_CRITICAL(...) SPDLOG_LOGGER_CRITICAL(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_CRITICAL(logger, ...) (void)0
|
||||
#define SPDLOG_CRITICAL(...) (void)0
|
||||
#endif
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "spdlog-inl.h"
|
||||
#endif
|
||||
|
||||
#endif // SPDLOG_H
|
||||
141
third_party/spdlog_headers/spdlog/tweakme.h
vendored
Normal file
141
third_party/spdlog_headers/spdlog/tweakme.h
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Edit this file to squeeze more performance, and to customize supported
|
||||
// features
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Under Linux, the much faster CLOCK_REALTIME_COARSE clock can be used.
|
||||
// This clock is less accurate - can be off by dozens of millis - depending on
|
||||
// the kernel HZ.
|
||||
// Uncomment to use it instead of the regular clock.
|
||||
//
|
||||
// #define SPDLOG_CLOCK_COARSE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment if source location logging is not needed.
|
||||
// This will prevent spdlog from using __FILE__, __LINE__ and SPDLOG_FUNCTION
|
||||
//
|
||||
// #define SPDLOG_NO_SOURCE_LOC
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment if thread id logging is not needed (i.e. no %t in the log pattern).
|
||||
// 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, zero will be logged as thread id.
|
||||
//
|
||||
// #define SPDLOG_NO_THREAD_ID
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to prevent spdlog from using thread local storage.
|
||||
//
|
||||
// WARNING: if your program forks, UNCOMMENT this flag to prevent undefined
|
||||
// thread ids in the children logs.
|
||||
//
|
||||
// #define SPDLOG_NO_TLS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to avoid spdlog's usage of atomic log levels
|
||||
// Use only if your code never modifies a logger's log levels concurrently by
|
||||
// different threads.
|
||||
//
|
||||
// #define SPDLOG_NO_ATOMIC_LEVELS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to enable usage of wchar_t for file names on Windows.
|
||||
//
|
||||
// #define SPDLOG_WCHAR_FILENAMES
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to override default eol ("\n" or "\r\n" under Linux/Windows)
|
||||
//
|
||||
// #define SPDLOG_EOL ";-)\n"
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to override default folder separators ("/" or "\\/" under
|
||||
// Linux/Windows). Each character in the string is treated as a different
|
||||
// separator.
|
||||
//
|
||||
// #define SPDLOG_FOLDER_SEPS "\\"
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to use your own copy of the fmt library instead of spdlog's copy.
|
||||
// In this case spdlog will try to include <fmt/format.h> so set your -I flag
|
||||
// accordingly.
|
||||
//
|
||||
// #define SPDLOG_FMT_EXTERNAL
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to use C++20 std::format instead of fmt.
|
||||
//
|
||||
// #define SPDLOG_USE_STD_FORMAT
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to enable wchar_t support (convert to utf8)
|
||||
//
|
||||
// #define SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to prevent child processes from inheriting log file descriptors
|
||||
//
|
||||
// #define SPDLOG_PREVENT_CHILD_FD
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to customize level names (e.g. "MY TRACE")
|
||||
//
|
||||
// #define SPDLOG_LEVEL_NAMES { "MY TRACE", "MY DEBUG", "MY INFO", "MY WARNING", "MY ERROR", "MY
|
||||
// CRITICAL", "OFF" }
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to customize short level names (e.g. "MT")
|
||||
// These can be longer than one character.
|
||||
//
|
||||
// #define SPDLOG_SHORT_LEVEL_NAMES { "T", "D", "I", "W", "E", "C", "O" }
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to disable default logger creation.
|
||||
// This might save some (very) small initialization time if no default logger is needed.
|
||||
//
|
||||
// #define SPDLOG_DISABLE_DEFAULT_LOGGER
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment and set to compile time level with zero cost (default is INFO).
|
||||
// Macros like SPDLOG_DEBUG(..), SPDLOG_INFO(..) will expand to empty statements if not enabled
|
||||
//
|
||||
// #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment (and change if desired) macro to use for function names.
|
||||
// This is compiler dependent.
|
||||
// __PRETTY_FUNCTION__ might be nicer in clang/gcc, and __FUNCTION__ in msvc.
|
||||
// Defaults to __FUNCTION__ (should work on all compilers) if not defined.
|
||||
//
|
||||
// #ifdef __PRETTY_FUNCTION__
|
||||
// # define SPDLOG_FUNCTION __PRETTY_FUNCTION__
|
||||
// #else
|
||||
// # define SPDLOG_FUNCTION __FUNCTION__
|
||||
// #endif
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
11
third_party/spdlog_headers/spdlog/version.h
vendored
Normal file
11
third_party/spdlog_headers/spdlog/version.h
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#define SPDLOG_VER_MAJOR 1
|
||||
#define SPDLOG_VER_MINOR 13
|
||||
#define SPDLOG_VER_PATCH 0
|
||||
|
||||
#define SPDLOG_TO_VERSION(major, minor, patch) (major * 10000 + minor * 100 + patch)
|
||||
#define SPDLOG_VERSION SPDLOG_TO_VERSION(SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH)
|
||||
Reference in New Issue
Block a user