From b1791c3078b6a3dac2e393ab57c5460d9893f295 Mon Sep 17 00:00:00 2001 From: Woochanlee Date: Wed, 7 Jul 2021 16:04:31 +0900 Subject: [PATCH] Aurum: Delete libloguru dependency Change-Id: I92b583cc4383093b63dac1ed99468ece395e6082 --- libaurum/meson.build | 3 - .../Accessibility/AtspiAccessibleWatcher.cc | 2 - libloguru/inc/loguru.hpp | 1335 ------------ libloguru/meson.build | 20 - libloguru/src/loguru.cpp | 1795 ----------------- meson.build | 1 - org.tizen.aurum-bootstrap/meson.build | 3 - tests/Test_Misc.cc | 3 - tests/Test_Sel.cc | 4 - tests/Test_UiDevice.cc | 7 +- tests/Test_UiObject.cc | 4 +- tests/Test_UiSelector.cc | 2 - 12 files changed, 2 insertions(+), 3177 deletions(-) delete mode 100644 libloguru/inc/loguru.hpp delete mode 100644 libloguru/meson.build delete mode 100644 libloguru/src/loguru.cpp diff --git a/libaurum/meson.build b/libaurum/meson.build index 24d3c3b..d55c9ee 100644 --- a/libaurum/meson.build +++ b/libaurum/meson.build @@ -27,7 +27,6 @@ libaurum_inc = [ include_directories('./inc/Runnable'), include_directories('./inc/Interface'), root_inc, - loguru_inc, ] libaurum_src = [] @@ -37,7 +36,6 @@ libaurum_dep = [ dependency('atspi-2'), dependency('gio-2.0'), dependency('threads'), - loguru_deps, ] if get_option('tizen') == true @@ -53,7 +51,6 @@ endif libaurum_lib = library('aurum', libaurum_src, dependencies: libaurum_dep, include_directories: libaurum_inc, - link_with: libloguru, install: true, version: meson.project_version(), ) diff --git a/libaurum/src/Impl/Accessibility/AtspiAccessibleWatcher.cc b/libaurum/src/Impl/Accessibility/AtspiAccessibleWatcher.cc index b15e440..a2aaa49 100644 --- a/libaurum/src/Impl/Accessibility/AtspiAccessibleWatcher.cc +++ b/libaurum/src/Impl/Accessibility/AtspiAccessibleWatcher.cc @@ -11,8 +11,6 @@ #include #include -#include - std::vector> AtspiAccessibleWatcher::mEventQueue; GThread *AtspiAccessibleWatcher::mEventThread = nullptr; diff --git a/libloguru/inc/loguru.hpp b/libloguru/inc/loguru.hpp deleted file mode 100644 index 24eca7a..0000000 --- a/libloguru/inc/loguru.hpp +++ /dev/null @@ -1,1335 +0,0 @@ -/* -Loguru logging library for C++, by Emil Ernerfeldt. -www.github.com/emilk/loguru -If you find Loguru useful, please let me know on twitter or in a mail! -Twitter: @ernerfeldt -Mail: emil.ernerfeldt@gmail.com -Website: www.ilikebigbits.com - -# License - This software is in the public domain. Where that dedication is not - recognized, you are granted a perpetual, irrevocable license to - copy, modify and distribute it as you see fit. - -# Inspiration - Much of Loguru was inspired by GLOG, https://code.google.com/p/google-glog/. - The choice of public domain is fully due Sean T. Barrett - and his wonderful stb libraries at https://github.com/nothings/stb. - -# Version history - * Version 0.1.0 - 2015-03-22 - Works great on Mac. - * Version 0.2.0 - 2015-09-17 - Removed the only dependency. - * Version 0.3.0 - 2015-10-02 - Drop-in replacement for most of GLOG - * Version 0.4.0 - 2015-10-07 - Single-file! - * Version 0.5.0 - 2015-10-17 - Improved file logging - * Version 0.6.0 - 2015-10-24 - Add stack traces - * Version 0.7.0 - 2015-10-27 - Signals - * Version 0.8.0 - 2015-10-30 - Color logging. - * Version 0.9.0 - 2015-11-26 - ABORT_S and proper handling of FATAL - * Version 1.0.0 - 2016-02-14 - ERROR_CONTEXT - * Version 1.1.0 - 2016-02-19 - -v OFF, -v INFO etc - * Version 1.1.1 - 2016-02-20 - textprintf vs strprintf - * Version 1.1.2 - 2016-02-22 - Remove g_alsologtostderr - * Version 1.1.3 - 2016-02-29 - ERROR_CONTEXT as linked list - * Version 1.2.0 - 2016-03-19 - Add get_thread_name() - * Version 1.2.1 - 2016-03-20 - Minor fixes - * Version 1.2.2 - 2016-03-29 - Fix issues with set_fatal_handler throwing an exception - * Version 1.2.3 - 2016-05-16 - Log current working directory in loguru::init(). - * Version 1.2.4 - 2016-05-18 - Custom replacement for -v in loguru::init() by bjoernpollex - * Version 1.2.5 - 2016-05-18 - Add ability to print ERROR_CONTEXT of parent thread. - * Version 1.2.6 - 2016-05-19 - Bug fix regarding VLOG verbosity argument lacking (). - * Version 1.2.7 - 2016-05-23 - Fix PATH_MAX problem. - * Version 1.2.8 - 2016-05-26 - Add shutdown() and remove_all_callbacks() - * Version 1.2.9 - 2016-06-09 - Use a monotonic clock for uptime. - * Version 1.3.0 - 2016-07-20 - Fix issues with callback flush/close not being called. - * Version 1.3.1 - 2016-07-20 - Add LOGURU_UNSAFE_SIGNAL_HANDLER to toggle stacktrace on signals. - * Version 1.3.2 - 2016-07-20 - Add loguru::arguments() - * Version 1.4.0 - 2016-09-15 - Semantic versioning + add loguru::create_directories - * Version 1.4.1 - 2016-09-29 - Customize formating with LOGURU_FILENAME_WIDTH - * Version 1.5.0 - 2016-12-22 - LOGURU_USE_FMTLIB by kolis and LOGURU_WITH_FILEABS by scinart - * Version 1.5.1 - 2017-08-08 - Terminal colors on Windows 10 thanks to looki - * Version 1.6.0 - 2018-01-03 - Add LOGURU_RTTI and LOGURU_STACKTRACES settings - * Version 1.7.0 - 2018-01-03 - Add ability to turn off the preamble with loguru::g_preamble - * Version 1.7.1 - 2018-04-05 - Add function get_fatal_handler - * Version 1.7.2 - 2018-04-22 - Fix a bug where large file names could cause stack corruption (thanks @ccamporesi) - * Version 1.8.0 - 2018-04-23 - Shorten long file names to keep preamble fixed width - * Version 1.9.0 - 2018-09-22 - Adjust terminal colors, add LOGURU_VERBOSE_SCOPE_ENDINGS, add LOGURU_SCOPE_TIME_PRECISION, add named log levels - * Version 2.0.0 - 2018-09-22 - Split loguru.hpp into loguru.hpp and loguru.cpp - -# Compiling - Just include where you want to use Loguru. - Then, in one .cpp file #include - Make sure you compile with -std=c++11 -lstdc++ -lpthread -ldl - -# Usage - For details, please see the official documentation at emilk.github.io/loguru - - #include - - int main(int argc, char* argv[]) { - loguru::init(argc, argv); - - // Put every log message in "everything.log": - loguru::add_file("everything.log", loguru::Append, loguru::Verbosity_MAX); - - LOG_F(INFO, "The magic number is %d", 42); - } - -*/ - -#if defined(LOGURU_IMPLEMENTATION) - #warning "You are defining LOGURU_IMPLEMENTATION. This is for older versions of Loguru. You should now instead include loguru.cpp (or build it and link with it)" -#endif - -// Disable all warnings from gcc/clang: -#if defined(__clang__) - #pragma clang system_header -#elif defined(__GNUC__) - #pragma GCC system_header -#endif - -#ifndef LOGURU_HAS_DECLARED_FORMAT_HEADER -#define LOGURU_HAS_DECLARED_FORMAT_HEADER - -// Semantic versioning. Loguru version can be printed with printf("%d.%d.%d", LOGURU_VERSION_MAJOR, LOGURU_VERSION_MINOR, LOGURU_VERSION_PATCH); -#define LOGURU_VERSION_MAJOR 2 -#define LOGURU_VERSION_MINOR 0 -#define LOGURU_VERSION_PATCH 0 - -#if defined(_MSC_VER) -#include // Needed for _In_z_ etc annotations -#endif - -// ---------------------------------------------------------------------------- - -#ifndef LOGURU_EXPORT - // Define to your project's export declaration if needed for use in a shared library. - #define LOGURU_EXPORT -#endif - -#ifndef LOGURU_SCOPE_TEXT_SIZE - // Maximum length of text that can be printed by a LOG_SCOPE. - // This should be long enough to get most things, but short enough not to clutter the stack. - #define LOGURU_SCOPE_TEXT_SIZE 196 -#endif - -#ifndef LOGURU_FILENAME_WIDTH - // Width of the column containing the file name - #define LOGURU_FILENAME_WIDTH 23 -#endif - -#ifndef LOGURU_THREADNAME_WIDTH - // Width of the column containing the thread name - #define LOGURU_THREADNAME_WIDTH 16 -#endif - -#ifndef LOGURU_SCOPE_TIME_PRECISION - // Resolution of scope timers. 3=ms, 6=us, 9=ns - #define LOGURU_SCOPE_TIME_PRECISION 3 -#endif - -#ifndef LOGURU_CATCH_SIGABRT - // Should Loguru catch SIGABRT to print stack trace etc? - #define LOGURU_CATCH_SIGABRT 1 -#endif - -#ifndef LOGURU_VERBOSE_SCOPE_ENDINGS - // Show milliseconds and scope name at end of scope. - #define LOGURU_VERBOSE_SCOPE_ENDINGS 1 -#endif - -#ifndef LOGURU_REDEFINE_ASSERT - #define LOGURU_REDEFINE_ASSERT 0 -#endif - -#ifndef LOGURU_WITH_STREAMS - #define LOGURU_WITH_STREAMS 0 -#endif - -#ifndef LOGURU_REPLACE_GLOG - #define LOGURU_REPLACE_GLOG 0 -#endif - -#if LOGURU_REPLACE_GLOG - #undef LOGURU_WITH_STREAMS - #define LOGURU_WITH_STREAMS 1 -#endif - -#ifndef LOGURU_UNSAFE_SIGNAL_HANDLER - #define LOGURU_UNSAFE_SIGNAL_HANDLER 1 -#endif - -#if LOGURU_IMPLEMENTATION - #undef LOGURU_WITH_STREAMS - #define LOGURU_WITH_STREAMS 1 -#endif - -#ifndef LOGURU_USE_FMTLIB - #define LOGURU_USE_FMTLIB 0 -#endif - -#ifndef LOGURU_WITH_FILEABS - #define LOGURU_WITH_FILEABS 0 -#endif - -#ifndef LOGURU_RTTI -#if defined(__clang__) - #if __has_feature(cxx_rtti) - #define LOGURU_RTTI 1 - #endif -#elif defined(__GNUG__) - #if defined(__GXX_RTTI) - #define LOGURU_RTTI 1 - #endif -#elif defined(_MSC_VER) - #if defined(_CPPRTTI) - #define LOGURU_RTTI 1 - #endif -#endif -#endif - -// -------------------------------------------------------------------- -// Utility macros - -#define LOGURU_CONCATENATE_IMPL(s1, s2) s1 ## s2 -#define LOGURU_CONCATENATE(s1, s2) LOGURU_CONCATENATE_IMPL(s1, s2) - -#ifdef __COUNTER__ -# define LOGURU_ANONYMOUS_VARIABLE(str) LOGURU_CONCATENATE(str, __COUNTER__) -#else -# define LOGURU_ANONYMOUS_VARIABLE(str) LOGURU_CONCATENATE(str, __LINE__) -#endif - -#if defined(__clang__) || defined(__GNUC__) - // Helper macro for declaring functions as having similar signature to printf. - // This allows the compiler to catch format errors at compile-time. - #define LOGURU_PRINTF_LIKE(fmtarg, firstvararg) __attribute__((__format__ (__printf__, fmtarg, firstvararg))) - #define LOGURU_FORMAT_STRING_TYPE const char* -#elif defined(_MSC_VER) - #define LOGURU_PRINTF_LIKE(fmtarg, firstvararg) - #define LOGURU_FORMAT_STRING_TYPE _In_z_ _Printf_format_string_ const char* -#else - #define LOGURU_PRINTF_LIKE(fmtarg, firstvararg) - #define LOGURU_FORMAT_STRING_TYPE const char* -#endif - -// Used to mark log_and_abort for the benefit of the static analyzer and optimizer. -#if defined(_MSC_VER) -#define LOGURU_NORETURN __declspec(noreturn) -#else -#define LOGURU_NORETURN __attribute__((noreturn)) -#endif - -#if defined(_MSC_VER) -#define LOGURU_PREDICT_FALSE(x) (x) -#define LOGURU_PREDICT_TRUE(x) (x) -#else -#define LOGURU_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#define LOGURU_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -#endif - -#if LOGURU_USE_FMTLIB - #include -#endif - -#ifdef _WIN32 - #define STRDUP(str) _strdup(str) -#else - #define STRDUP(str) strdup(str) -#endif - -// -------------------------------------------------------------------- - -namespace loguru -{ - // Simple RAII ownership of a char*. - class LOGURU_EXPORT Text - { - public: - explicit Text(char* owned_str) : _str(owned_str) {} - ~Text(); - Text(Text&& t) - { - _str = t._str; - t._str = nullptr; - } - Text(Text& t) = delete; - Text& operator=(Text& t) = delete; - void operator=(Text&& t) = delete; - - const char* c_str() const { return _str; } - bool empty() const { return _str == nullptr || *_str == '\0'; } - - char* release() - { - auto result = _str; - _str = nullptr; - return result; - } - - private: - char* _str; - }; - - // Like printf, but returns the formated text. - LOGURU_EXPORT - Text textprintf(LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(1, 2); - - // Overloaded for variadic template matching. - LOGURU_EXPORT - Text textprintf(); - - using Verbosity = int; - -#undef FATAL -#undef ERROR -#undef WARNING -#undef INFO -#undef MAX - - enum NamedVerbosity : Verbosity - { - // Used to mark an invalid verbosity. Do not log to this level. - Verbosity_INVALID = -10, // Never do LOG_F(INVALID) - - // You may use Verbosity_OFF on g_stderr_verbosity, but for nothing else! - Verbosity_OFF = -9, // Never do LOG_F(OFF) - - // Prefer to use ABORT_F or ABORT_S over LOG_F(FATAL) or LOG_S(FATAL). - Verbosity_FATAL = -3, - Verbosity_ERROR = -2, - Verbosity_WARNING = -1, - - // Normal messages. By default written to stderr. - Verbosity_INFO = 0, - - // Same as Verbosity_INFO in every way. - Verbosity_0 = 0, - - // Verbosity levels 1-9 are generally not written to stderr, but are written to file. - Verbosity_1 = +1, - Verbosity_2 = +2, - Verbosity_3 = +3, - Verbosity_4 = +4, - Verbosity_5 = +5, - Verbosity_6 = +6, - Verbosity_7 = +7, - Verbosity_8 = +8, - Verbosity_9 = +9, - - // Don not use higher verbosity levels, as that will make grepping log files harder. - Verbosity_MAX = +9, - }; - - struct Message - { - // You would generally print a Message by just concating the buffers without spacing. - // Optionally, ignore preamble and indentation. - Verbosity verbosity; // Already part of preamble - const char* filename; // Already part of preamble - unsigned line; // Already part of preamble - const char* preamble; // Date, time, uptime, thread, file:line, verbosity. - const char* indentation; // Just a bunch of spacing. - const char* prefix; // Assertion failure info goes here (or ""). - const char* message; // User message goes here. - }; - - /* Everything with a verbosity equal or greater than g_stderr_verbosity will be - written to stderr. You can set this in code or via the -v argument. - Set to loguru::Verbosity_OFF to write nothing to stderr. - Default is 0, i.e. only log ERROR, WARNING and INFO are written to stderr. - */ - LOGURU_EXPORT extern Verbosity g_stderr_verbosity; - LOGURU_EXPORT extern bool g_colorlogtostderr; // True by default. - LOGURU_EXPORT extern unsigned g_flush_interval_ms; // 0 (unbuffered) by default. - LOGURU_EXPORT extern bool g_preamble; // Prefix each log line with date, time etc? True by default. - - /* Specify the verbosity used by loguru to log its info messages including the header - logged when logged::init() is called or on exit. Default is 0 (INFO). - */ - LOGURU_EXPORT extern Verbosity g_internal_verbosity; - - // Turn off individual parts of the preamble - LOGURU_EXPORT extern bool g_preamble_date; // The date field - LOGURU_EXPORT extern bool g_preamble_time; // The time of the current day - LOGURU_EXPORT extern bool g_preamble_uptime; // The time since init call - LOGURU_EXPORT extern bool g_preamble_thread; // The logging thread - LOGURU_EXPORT extern bool g_preamble_file; // The file from which the log originates from - LOGURU_EXPORT extern bool g_preamble_verbose; // The verbosity field - LOGURU_EXPORT extern bool g_preamble_pipe; // The pipe symbol right before the message - - // May not throw! - typedef void (*log_handler_t)(void* user_data, const Message& message); - typedef void (*close_handler_t)(void* user_data); - typedef void (*flush_handler_t)(void* user_data); - - // May throw if that's how you'd like to handle your errors. - typedef void (*fatal_handler_t)(const Message& message); - - // Given a verbosity level, return the level's name or nullptr. - typedef const char* (*verbosity_to_name_t)(Verbosity verbosity); - - // Given a verbosity level name, return the verbosity level or - // Verbosity_INVALID if name is not recognized. - typedef Verbosity (*name_to_verbosity_t)(const char* name); - - /* Should be called from the main thread. - You don't *need* to call this, but if you do you get: - * Signal handlers installed - * Program arguments logged - * Working dir logged - * Optional -v verbosity flag parsed - * Main thread name set to "main thread" - * Explanation of the preamble (date, threanmae etc) logged - - loguru::init() will look for arguments meant for loguru and remove them. - Arguments meant for loguru are: - -v n Set loguru::g_stderr_verbosity level. Examples: - -v 3 Show verbosity level 3 and lower. - -v 0 Only show INFO, WARNING, ERROR, FATAL (default). - -v INFO Only show INFO, WARNING, ERROR, FATAL (default). - -v WARNING Only show WARNING, ERROR, FATAL. - -v ERROR Only show ERROR, FATAL. - -v FATAL Only show FATAL. - -v OFF Turn off logging to stderr. - - Tip: You can set g_stderr_verbosity before calling loguru::init. - That way you can set the default but have the user override it with the -v flag. - Note that -v does not affect file logging (see loguru::add_file). - - You can use something else instead of "-v" via verbosity_flag. - You can also set verbosity_flag to nullptr. - */ - LOGURU_EXPORT - void init(int& argc, char* argv[], const char* verbosity_flag = "-v"); - - // Will call remove_all_callbacks(). After calling this, logging will still go to stderr. - // You generally don't need to call this. - LOGURU_EXPORT - void shutdown(); - - // What ~ will be replaced with, e.g. "/home/your_user_name/" - LOGURU_EXPORT - const char* home_dir(); - - /* Returns the name of the app as given in argv[0] but without leading path. - That is, if argv[0] is "../foo/app" this will return "app". - */ - LOGURU_EXPORT - const char* argv0_filename(); - - // Returns all arguments given to loguru::init(), but escaped with a single space as separator. - LOGURU_EXPORT - const char* arguments(); - - // Returns the path to the current working dir when loguru::init() was called. - LOGURU_EXPORT - const char* current_dir(); - - // Returns the part of the path after the last / or \ (if any). - LOGURU_EXPORT - const char* filename(const char* path); - - // e.g. "foo/bar/baz.ext" will create the directories "foo/" and "foo/bar/" - LOGURU_EXPORT - bool create_directories(const char* file_path_const); - - // Writes date and time with millisecond precision, e.g. "20151017_161503.123" - LOGURU_EXPORT - void write_date_time(char* buff, unsigned buff_size); - - // Helper: thread-safe version strerror - LOGURU_EXPORT - Text errno_as_text(); - - /* Given a prefix of e.g. "~/loguru/" this might return - "/home/your_username/loguru/app_name/20151017_161503.123.log" - - where "app_name" is a sanitized version of argv[0]. - */ - LOGURU_EXPORT - void suggest_log_path(const char* prefix, char* buff, unsigned buff_size); - - enum FileMode { Truncate, Append }; - - /* Will log to a file at the given path. - Any logging message with a verbosity lower or equal to - the given verbosity will be included. - The function will create all directories in 'path' if needed. - If path starts with a ~, it will be replaced with loguru::home_dir() - To stop the file logging, just call loguru::remove_callback(path) with the same path. - */ - LOGURU_EXPORT - bool add_file(const char* path, FileMode mode, Verbosity verbosity); - - /* Will be called right before abort(). - You can for instance use this to print custom error messages, or throw an exception. - Feel free to call LOG:ing function from this, but not FATAL ones! */ - LOGURU_EXPORT - void set_fatal_handler(fatal_handler_t handler); - - // Get the current fatal handler, if any. Default value is nullptr. - LOGURU_EXPORT - fatal_handler_t get_fatal_handler(); - - /* Will be called on each log messages with a verbosity less or equal to the given one. - Useful for displaying messages on-screen in a game, for example. - The given on_close is also expected to flush (if desired). - */ - LOGURU_EXPORT - void add_callback( - const char* id, - log_handler_t callback, - void* user_data, - Verbosity verbosity, - close_handler_t on_close = nullptr, - flush_handler_t on_flush = nullptr); - - /* Set a callback that returns custom verbosity level names. If callback - is nullptr or returns nullptr, default log names will be used. - */ - LOGURU_EXPORT - void set_verbosity_to_name_callback(verbosity_to_name_t callback); - - /* Set a callback that returns the verbosity level matching a name. The - callback should return Verbosity_INVALID if the name is not - recognized. - */ - LOGURU_EXPORT - void set_name_to_verbosity_callback(name_to_verbosity_t callback); - - /* Get a custom name for a specific verbosity, if one exists, or nullptr. */ - LOGURU_EXPORT - const char* get_verbosity_name(Verbosity verbosity); - - /* Get the verbosity enum value from a custom 4-character level name, if one exists. - If the name does not match a custom level name, Verbosity_INVALID is returned. - */ - LOGURU_EXPORT - Verbosity get_verbosity_from_name(const char* name); - - // Returns true iff the callback was found (and removed). - LOGURU_EXPORT - bool remove_callback(const char* id); - - // Shut down all file logging and any other callback hooks installed. - LOGURU_EXPORT - void remove_all_callbacks(); - - // Returns the maximum of g_stderr_verbosity and all file/custom outputs. - LOGURU_EXPORT - Verbosity current_verbosity_cutoff(); - -#if LOGURU_USE_FMTLIB - // Actual logging function. Use the LOG macro instead of calling this directly. - LOGURU_EXPORT - void log(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, fmt::ArgList args); - FMT_VARIADIC(void, log, Verbosity, const char*, unsigned, LOGURU_FORMAT_STRING_TYPE) - - // Log without any preamble or indentation. - LOGURU_EXPORT - void raw_log(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, fmt::ArgList args); - FMT_VARIADIC(void, raw_log, Verbosity, const char*, unsigned, LOGURU_FORMAT_STRING_TYPE) -#else // LOGURU_USE_FMTLIB? - // Actual logging function. Use the LOG macro instead of calling this directly. - LOGURU_EXPORT - void log(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(4, 5); - - // Log without any preamble or indentation. - LOGURU_EXPORT - void raw_log(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(4, 5); -#endif // !LOGURU_USE_FMTLIB - - // Helper class for LOG_SCOPE_F - class LOGURU_EXPORT LogScopeRAII - { - public: - LogScopeRAII() : _file(nullptr) {} // No logging - LogScopeRAII(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(5, 6); - ~LogScopeRAII(); - -#if defined(_MSC_VER) && _MSC_VER > 1800 - // older MSVC default move ctors close the scope on move. See - // issue #43 - LogScopeRAII(LogScopeRAII&& other) - : _verbosity(other._verbosity) - , _file(other._file) - , _line(other._line) - , _indent_stderr(other._indent_stderr) - , _start_time_ns(other._start_time_ns) - { - // Make sure the tmp object's destruction doesn't close the scope: - other._file = nullptr; - - for (unsigned int i = 0; i < LOGURU_SCOPE_TEXT_SIZE; ++i) { - _name[i] = other._name[i]; - } - } -#else - LogScopeRAII(LogScopeRAII&&) = default; -#endif - - private: - LogScopeRAII(const LogScopeRAII&) = delete; - LogScopeRAII& operator=(const LogScopeRAII&) = delete; - void operator=(LogScopeRAII&&) = delete; - - Verbosity _verbosity; - const char* _file; // Set to null if we are disabled due to verbosity - unsigned _line; - bool _indent_stderr; // Did we? - long long _start_time_ns; - char _name[LOGURU_SCOPE_TEXT_SIZE]; - }; - - // Marked as 'noreturn' for the benefit of the static analyzer and optimizer. - // stack_trace_skip is the number of extrace stack frames to skip above log_and_abort. - LOGURU_EXPORT - LOGURU_NORETURN void log_and_abort(int stack_trace_skip, const char* expr, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(5, 6); - LOGURU_EXPORT - LOGURU_NORETURN void log_and_abort(int stack_trace_skip, const char* expr, const char* file, unsigned line); - - // Flush output to stderr and files. - // If g_flush_interval_ms is set to non-zero, this will be called automatically this often. - // If not set, you do not need to call this at all. - LOGURU_EXPORT - void flush(); - - template inline Text format_value(const T&) { return textprintf("N/A"); } - template<> inline Text format_value(const char& v) { return textprintf("%c", v); } - template<> inline Text format_value(const int& v) { return textprintf("%d", v); } - template<> inline Text format_value(const unsigned int& v) { return textprintf("%u", v); } - template<> inline Text format_value(const long& v) { return textprintf("%lu", v); } - template<> inline Text format_value(const unsigned long& v) { return textprintf("%ld", v); } - template<> inline Text format_value(const long long& v) { return textprintf("%llu", v); } - template<> inline Text format_value(const unsigned long long& v) { return textprintf("%lld", v); } - template<> inline Text format_value(const float& v) { return textprintf("%f", v); } - template<> inline Text format_value(const double& v) { return textprintf("%f", v); } - - /* Thread names can be set for the benefit of readable logs. - If you do not set the thread name, a hex id will be shown instead. - These thread names may or may not be the same as the system thread names, - depending on the system. - Try to limit the thread name to 15 characters or less. */ - LOGURU_EXPORT - void set_thread_name(const char* name); - - /* Returns the thread name for this thread. - On OSX this will return the system thread name (settable from both within and without Loguru). - On other systems it will return whatever you set in set_thread_name(); - If no thread name is set, this will return a hexadecimal thread id. - length should be the number of bytes available in the buffer. - 17 is a good number for length. - right_align_hext_id means any hexadecimal thread id will be written to the end of buffer. - */ - LOGURU_EXPORT - void get_thread_name(char* buffer, unsigned long long length, bool right_align_hext_id); - - /* Generates a readable stacktrace as a string. - 'skip' specifies how many stack frames to skip. - For instance, the default skip (1) means: - don't include the call to loguru::stacktrace in the stack trace. */ - LOGURU_EXPORT - Text stacktrace(int skip = 1); - - /* Add a string to be replaced with something else in the stack output. - - For instance, instead of having a stack trace look like this: - 0x41f541 some_function(std::basic_ofstream >&) - You can clean it up with: - auto verbose_type_name = loguru::demangle(typeid(std::ofstream).name()); - loguru::add_stack_cleanup(verbose_type_name.c_str(); "std::ofstream"); - So the next time you will instead see: - 0x41f541 some_function(std::ofstream&) - - `replace_with_this` must be shorter than `find_this`. - */ - LOGURU_EXPORT - void add_stack_cleanup(const char* find_this, const char* replace_with_this); - - // Example: demangle(typeid(std::ofstream).name()) -> "std::basic_ofstream >" - LOGURU_EXPORT - Text demangle(const char* name); - - // ------------------------------------------------------------------------ - /* - Not all terminals support colors, but if they do, and g_colorlogtostderr - is set, Loguru will write them to stderr to make errors in red, etc. - - You also have the option to manually use them, via the function below. - - Note, however, that if you do, the color codes could end up in your logfile! - - This means if you intend to use them functions you should either: - * Use them on the stderr/stdout directly (bypass Loguru). - * Don't add file outputs to Loguru. - * Expect some \e[1m things in your logfile. - - Usage: - printf("%sRed%sGreen%sBold green%sClear again\n", - loguru::terminal_red(), loguru::terminal_green(), - loguru::terminal_bold(), loguru::terminal_reset()); - - If the terminal at hand does not support colors the above output - will just not have funky \e[1m things showing. - */ - - // Do the output terminal support colors? - LOGURU_EXPORT - bool terminal_has_color(); - - // Colors - LOGURU_EXPORT const char* terminal_black(); - LOGURU_EXPORT const char* terminal_red(); - LOGURU_EXPORT const char* terminal_green(); - LOGURU_EXPORT const char* terminal_yellow(); - LOGURU_EXPORT const char* terminal_blue(); - LOGURU_EXPORT const char* terminal_purple(); - LOGURU_EXPORT const char* terminal_cyan(); - LOGURU_EXPORT const char* terminal_light_gray(); - LOGURU_EXPORT const char* terminal_light_red(); - LOGURU_EXPORT const char* terminal_white(); - - // Formating - LOGURU_EXPORT const char* terminal_bold(); - LOGURU_EXPORT const char* terminal_underline(); - - // You should end each line with this! - LOGURU_EXPORT const char* terminal_reset(); - - // -------------------------------------------------------------------- - // Error context related: - - struct StringStream; - - // Use this in your EcEntryBase::print_value overload. - LOGURU_EXPORT - void stream_print(StringStream& out_string_stream, const char* text); - - class LOGURU_EXPORT EcEntryBase - { - public: - EcEntryBase(const char* file, unsigned line, const char* descr); - ~EcEntryBase(); - EcEntryBase(const EcEntryBase&) = delete; - EcEntryBase(EcEntryBase&&) = delete; - EcEntryBase& operator=(const EcEntryBase&) = delete; - EcEntryBase& operator=(EcEntryBase&&) = delete; - - virtual void print_value(StringStream& out_string_stream) const = 0; - - EcEntryBase* previous() const { return _previous; } - - // private: - const char* _file; - unsigned _line; - const char* _descr; - EcEntryBase* _previous; - }; - - template - class EcEntryData : public EcEntryBase - { - public: - using Printer = Text(*)(T data); - - EcEntryData(const char* file, unsigned line, const char* descr, T data, Printer&& printer) - : EcEntryBase(file, line, descr), _data(data), _printer(printer) {} - - virtual void print_value(StringStream& out_string_stream) const override - { - const auto str = _printer(_data); - stream_print(out_string_stream, str.c_str()); - } - - private: - T _data; - Printer _printer; - }; - - // template - // class EcEntryLambda : public EcEntryBase - // { - // public: - // EcEntryLambda(const char* file, unsigned line, const char* descr, Printer&& printer) - // : EcEntryBase(file, line, descr), _printer(std::move(printer)) {} - - // virtual void print_value(StringStream& out_string_stream) const override - // { - // const auto str = _printer(); - // stream_print(out_string_stream, str.c_str()); - // } - - // private: - // Printer _printer; - // }; - - // template - // EcEntryLambda make_ec_entry_lambda(const char* file, unsigned line, const char* descr, Printer&& printer) - // { - // return {file, line, descr, std::move(printer)}; - // } - - template - struct decay_char_array { using type = T; }; - - template - struct decay_char_array { using type = const char*; }; - - template - struct make_const_ptr { using type = T; }; - - template - struct make_const_ptr { using type = const T*; }; - - template - struct make_ec_type { using type = typename make_const_ptr::type>::type; }; - - /* A stack trace gives you the names of the function at the point of a crash. - With ERROR_CONTEXT, you can also get the values of select local variables. - Usage: - - void process_customers(const std::string& filename) - { - ERROR_CONTEXT("Processing file", filename.c_str()); - for (int customer_index : ...) - { - ERROR_CONTEXT("Customer index", customer_index); - ... - } - } - - The context is in effect during the scope of the ERROR_CONTEXT. - Use loguru::get_error_context() to get the contents of the active error contexts. - - Example result: - - ------------------------------------------------ - [ErrorContext] main.cpp:416 Processing file: "customers.json" - [ErrorContext] main.cpp:417 Customer index: 42 - ------------------------------------------------ - - Error contexts are printed automatically on crashes, and only on crashes. - This makes them much faster than logging the value of a variable. - */ - #define ERROR_CONTEXT(descr, data) \ - const loguru::EcEntryData::type> \ - LOGURU_ANONYMOUS_VARIABLE(error_context_scope_)( \ - __FILE__, __LINE__, descr, data, \ - static_cast::type>::Printer>(loguru::ec_to_text) ) // For better error messages - -/* - #define ERROR_CONTEXT(descr, data) \ - const auto LOGURU_ANONYMOUS_VARIABLE(error_context_scope_)( \ - loguru::make_ec_entry_lambda(__FILE__, __LINE__, descr, \ - [=](){ return loguru::ec_to_text(data); })) -*/ - - using EcHandle = const EcEntryBase*; - - /* - Get a light-weight handle to the error context stack on this thread. - The handle is valid as long as the current thread has no changes to its error context stack. - You can pass the handle to loguru::get_error_context on another thread. - This can be very useful for when you have a parent thread spawning several working threads, - and you want the error context of the parent thread to get printed (too) when there is an - error on the child thread. You can accomplish this thusly: - - void foo(const char* parameter) - { - ERROR_CONTEXT("parameter", parameter) - const auto parent_ec_handle = loguru::get_thread_ec_handle(); - - std::thread([=]{ - loguru::set_thread_name("child thread"); - ERROR_CONTEXT("parent context", parent_ec_handle); - dangerous_code(); - }.join(); - } - - */ - LOGURU_EXPORT - EcHandle get_thread_ec_handle(); - - // Get a string describing the current stack of error context. Empty string if there is none. - LOGURU_EXPORT - Text get_error_context(); - - // Get a string describing the error context of the given thread handle. - LOGURU_EXPORT - Text get_error_context_for(EcHandle ec_handle); - - // ------------------------------------------------------------------------ - - LOGURU_EXPORT Text ec_to_text(const char* data); - LOGURU_EXPORT Text ec_to_text(char data); - LOGURU_EXPORT Text ec_to_text(int data); - LOGURU_EXPORT Text ec_to_text(unsigned int data); - LOGURU_EXPORT Text ec_to_text(long data); - LOGURU_EXPORT Text ec_to_text(unsigned long data); - LOGURU_EXPORT Text ec_to_text(long long data); - LOGURU_EXPORT Text ec_to_text(unsigned long long data); - LOGURU_EXPORT Text ec_to_text(float data); - LOGURU_EXPORT Text ec_to_text(double data); - LOGURU_EXPORT Text ec_to_text(long double data); - LOGURU_EXPORT Text ec_to_text(EcHandle); - - /* - You can add ERROR_CONTEXT support for your own types by overloading ec_to_text. Here's how: - - some.hpp: - namespace loguru { - Text ec_to_text(MySmallType data) - Text ec_to_text(const MyBigType* data) - } // namespace loguru - - some.cpp: - namespace loguru { - Text ec_to_text(MySmallType small_value) - { - // Called only when needed, i.e. on a crash. - std::string str = small_value.as_string(); // Format 'small_value' here somehow. - return Text{STRDUP(str.c_str())}; - } - - Text ec_to_text(const MyBigType* big_value) - { - // Called only when needed, i.e. on a crash. - std::string str = big_value->as_string(); // Format 'big_value' here somehow. - return Text{STRDUP(str.c_str())}; - } - } // namespace loguru - - Any file that include some.hpp: - void foo(MySmallType small, const MyBigType& big) - { - ERROR_CONTEXT("Small", small); // Copy ´small` by value. - ERROR_CONTEXT("Big", &big); // `big` should not change during this scope! - .... - } - */ -} // namespace loguru - -// -------------------------------------------------------------------- -// Logging macros - -// LOG_F(2, "Only logged if verbosity is 2 or higher: %d", some_number); -#define VLOG_F(verbosity, ...) \ - ((verbosity) > loguru::current_verbosity_cutoff()) ? (void)0 \ - : loguru::log(verbosity, __FILE__, __LINE__, __VA_ARGS__) - -// LOG_F(INFO, "Foo: %d", some_number); -#define LOG_F(verbosity_name, ...) VLOG_F(loguru::Verbosity_ ## verbosity_name, __VA_ARGS__) - -#define VLOG_IF_F(verbosity, cond, ...) \ - ((verbosity) > loguru::current_verbosity_cutoff() || (cond) == false) \ - ? (void)0 \ - : loguru::log(verbosity, __FILE__, __LINE__, __VA_ARGS__) - -#define LOG_IF_F(verbosity_name, cond, ...) \ - VLOG_IF_F(loguru::Verbosity_ ## verbosity_name, cond, __VA_ARGS__) - -#define VLOG_SCOPE_F(verbosity, ...) \ - loguru::LogScopeRAII LOGURU_ANONYMOUS_VARIABLE(error_context_RAII_) = \ - ((verbosity) > loguru::current_verbosity_cutoff()) ? loguru::LogScopeRAII() : \ - loguru::LogScopeRAII(verbosity, __FILE__, __LINE__, __VA_ARGS__) - -// Raw logging - no preamble, no indentation. Slightly faster than full logging. -#define RAW_VLOG_F(verbosity, ...) \ - ((verbosity) > loguru::current_verbosity_cutoff()) ? (void)0 \ - : loguru::raw_log(verbosity, __FILE__, __LINE__, __VA_ARGS__) - -#define RAW_LOG_F(verbosity_name, ...) RAW_VLOG_F(loguru::Verbosity_ ## verbosity_name, __VA_ARGS__) - -// Use to book-end a scope. Affects logging on all threads. -#define LOG_SCOPE_F(verbosity_name, ...) \ - VLOG_SCOPE_F(loguru::Verbosity_ ## verbosity_name, __VA_ARGS__) - -#define LOG_SCOPE_FUNCTION(verbosity_name) LOG_SCOPE_F(verbosity_name, __func__) - -// ----------------------------------------------- -// ABORT_F macro. Usage: ABORT_F("Cause of error: %s", error_str); - -// Message is optional -#define ABORT_F(...) loguru::log_and_abort(0, "ABORT: ", __FILE__, __LINE__, __VA_ARGS__) - -// -------------------------------------------------------------------- -// CHECK_F macros: - -#define CHECK_WITH_INFO_F(test, info, ...) \ - LOGURU_PREDICT_TRUE((test) == true) ? (void)0 : loguru::log_and_abort(0, "CHECK FAILED: " info " ", __FILE__, \ - __LINE__, ##__VA_ARGS__) - -/* Checked at runtime too. Will print error, then call fatal_handler (if any), then 'abort'. - Note that the test must be boolean. - CHECK_F(ptr); will not compile, but CHECK_F(ptr != nullptr); will. */ -#define CHECK_F(test, ...) CHECK_WITH_INFO_F(test, #test, ##__VA_ARGS__) - -#define CHECK_NOTNULL_F(x, ...) CHECK_WITH_INFO_F((x) != nullptr, #x " != nullptr", ##__VA_ARGS__) - -#define CHECK_OP_F(expr_left, expr_right, op, ...) \ - do \ - { \ - auto val_left = expr_left; \ - auto val_right = expr_right; \ - if (! LOGURU_PREDICT_TRUE(val_left op val_right)) \ - { \ - auto str_left = loguru::format_value(val_left); \ - auto str_right = loguru::format_value(val_right); \ - auto fail_info = loguru::textprintf("CHECK FAILED: %s %s %s (%s %s %s) ", \ - #expr_left, #op, #expr_right, str_left.c_str(), #op, str_right.c_str()); \ - auto user_msg = loguru::textprintf(__VA_ARGS__); \ - loguru::log_and_abort(0, fail_info.c_str(), __FILE__, __LINE__, \ - "%s", user_msg.c_str()); \ - } \ - } while (false) - -#ifndef LOGURU_DEBUG_LOGGING - #ifndef NDEBUG - #define LOGURU_DEBUG_LOGGING 1 - #else - #define LOGURU_DEBUG_LOGGING 0 - #endif -#endif - -#if LOGURU_DEBUG_LOGGING - // Debug logging enabled: - #define DLOG_F(verbosity_name, ...) LOG_F(verbosity_name, __VA_ARGS__) - #define DVLOG_F(verbosity, ...) VLOG_F(verbosity, __VA_ARGS__) - #define DLOG_IF_F(verbosity_name, ...) LOG_IF_F(verbosity_name, __VA_ARGS__) - #define DVLOG_IF_F(verbosity, ...) VLOG_IF_F(verbosity, __VA_ARGS__) - #define DRAW_LOG_F(verbosity_name, ...) RAW_LOG_F(verbosity_name, __VA_ARGS__) - #define DRAW_VLOG_F(verbosity, ...) RAW_VLOG_F(verbosity, __VA_ARGS__) -#else - // Debug logging disabled: - #define DLOG_F(verbosity_name, ...) - #define DVLOG_F(verbosity, ...) - #define DLOG_IF_F(verbosity_name, ...) - #define DVLOG_IF_F(verbosity, ...) - #define DRAW_LOG_F(verbosity_name, ...) - #define DRAW_VLOG_F(verbosity, ...) -#endif - -#define CHECK_EQ_F(a, b, ...) CHECK_OP_F(a, b, ==, ##__VA_ARGS__) -#define CHECK_NE_F(a, b, ...) CHECK_OP_F(a, b, !=, ##__VA_ARGS__) -#define CHECK_LT_F(a, b, ...) CHECK_OP_F(a, b, < , ##__VA_ARGS__) -#define CHECK_GT_F(a, b, ...) CHECK_OP_F(a, b, > , ##__VA_ARGS__) -#define CHECK_LE_F(a, b, ...) CHECK_OP_F(a, b, <=, ##__VA_ARGS__) -#define CHECK_GE_F(a, b, ...) CHECK_OP_F(a, b, >=, ##__VA_ARGS__) - -#ifndef LOGURU_DEBUG_CHECKS - #ifndef NDEBUG - #define LOGURU_DEBUG_CHECKS 1 - #else - #define LOGURU_DEBUG_CHECKS 0 - #endif -#endif - -#if LOGURU_DEBUG_CHECKS - // Debug checks enabled: - #define DCHECK_F(test, ...) CHECK_F(test, ##__VA_ARGS__) - #define DCHECK_NOTNULL_F(x, ...) CHECK_NOTNULL_F(x, ##__VA_ARGS__) - #define DCHECK_EQ_F(a, b, ...) CHECK_EQ_F(a, b, ##__VA_ARGS__) - #define DCHECK_NE_F(a, b, ...) CHECK_NE_F(a, b, ##__VA_ARGS__) - #define DCHECK_LT_F(a, b, ...) CHECK_LT_F(a, b, ##__VA_ARGS__) - #define DCHECK_LE_F(a, b, ...) CHECK_LE_F(a, b, ##__VA_ARGS__) - #define DCHECK_GT_F(a, b, ...) CHECK_GT_F(a, b, ##__VA_ARGS__) - #define DCHECK_GE_F(a, b, ...) CHECK_GE_F(a, b, ##__VA_ARGS__) -#else - // Debug checks disabled: - #define DCHECK_F(test, ...) - #define DCHECK_NOTNULL_F(x, ...) - #define DCHECK_EQ_F(a, b, ...) - #define DCHECK_NE_F(a, b, ...) - #define DCHECK_LT_F(a, b, ...) - #define DCHECK_LE_F(a, b, ...) - #define DCHECK_GT_F(a, b, ...) - #define DCHECK_GE_F(a, b, ...) -#endif // NDEBUG - - -#if LOGURU_REDEFINE_ASSERT - #undef assert - #ifndef NDEBUG - // Debug: - #define assert(test) CHECK_WITH_INFO_F(!!(test), #test) // HACK - #else - #define assert(test) - #endif -#endif // LOGURU_REDEFINE_ASSERT - -#endif // LOGURU_HAS_DECLARED_FORMAT_HEADER - -// ---------------------------------------------------------------------------- -// .dP"Y8 888888 88""Yb 888888 db 8b d8 .dP"Y8 -// `Ybo." 88 88__dP 88__ dPYb 88b d88 `Ybo." -// o.`Y8b 88 88"Yb 88"" dP__Yb 88YbdP88 o.`Y8b -// 8bodP' 88 88 Yb 888888 dP""""Yb 88 YY 88 8bodP' - -#if LOGURU_WITH_STREAMS -#ifndef LOGURU_HAS_DECLARED_STREAMS_HEADER -#define LOGURU_HAS_DECLARED_STREAMS_HEADER - -/* This file extends loguru to enable std::stream-style logging, a la Glog. - It's an optional feature behind the LOGURU_WITH_STREAMS settings - because including it everywhere will slow down compilation times. -*/ - -#include -#include // Adds about 38 kLoC on clang. -#include - -namespace loguru -{ - // Like sprintf, but returns the formated text. - LOGURU_EXPORT - std::string strprintf(LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(1, 2); - - // Like vsprintf, but returns the formated text. - LOGURU_EXPORT - std::string vstrprintf(LOGURU_FORMAT_STRING_TYPE format, va_list) LOGURU_PRINTF_LIKE(1, 0); - - class LOGURU_EXPORT StreamLogger - { - public: - StreamLogger(Verbosity verbosity, const char* file, unsigned line) : _verbosity(verbosity), _file(file), _line(line) {} - ~StreamLogger() noexcept(false); - - template - StreamLogger& operator<<(const T& t) - { - _ss << t; - return *this; - } - - // std::endl and other iomanip:s. - StreamLogger& operator<<(std::ostream&(*f)(std::ostream&)) - { - f(_ss); - return *this; - } - - private: - Verbosity _verbosity; - const char* _file; - unsigned _line; - std::ostringstream _ss; - }; - - class LOGURU_EXPORT AbortLogger - { - public: - AbortLogger(const char* expr, const char* file, unsigned line) : _expr(expr), _file(file), _line(line) { } - LOGURU_NORETURN ~AbortLogger() noexcept(false); - - template - AbortLogger& operator<<(const T& t) - { - _ss << t; - return *this; - } - - // std::endl and other iomanip:s. - AbortLogger& operator<<(std::ostream&(*f)(std::ostream&)) - { - f(_ss); - return *this; - } - - private: - const char* _expr; - const char* _file; - unsigned _line; - std::ostringstream _ss; - }; - - class LOGURU_EXPORT Voidify - { - public: - Voidify() {} - // This has to be an operator with a precedence lower than << but higher than ?: - void operator&(const StreamLogger&) { } - void operator&(const AbortLogger&) { } - }; - - /* Helper functions for CHECK_OP_S macro. - GLOG trick: The (int, int) specialization works around the issue that the compiler - will not instantiate the template version of the function on values of unnamed enum type. */ - #define DEFINE_CHECK_OP_IMPL(name, op) \ - template \ - inline std::string* name(const char* expr, const T1& v1, const char* op_str, const T2& v2) \ - { \ - if (LOGURU_PREDICT_TRUE(v1 op v2)) { return NULL; } \ - std::ostringstream ss; \ - ss << "CHECK FAILED: " << expr << " (" << v1 << " " << op_str << " " << v2 << ") "; \ - return new std::string(ss.str()); \ - } \ - inline std::string* name(const char* expr, int v1, const char* op_str, int v2) \ - { \ - return name(expr, v1, op_str, v2); \ - } - - DEFINE_CHECK_OP_IMPL(check_EQ_impl, ==) - DEFINE_CHECK_OP_IMPL(check_NE_impl, !=) - DEFINE_CHECK_OP_IMPL(check_LE_impl, <=) - DEFINE_CHECK_OP_IMPL(check_LT_impl, < ) - DEFINE_CHECK_OP_IMPL(check_GE_impl, >=) - DEFINE_CHECK_OP_IMPL(check_GT_impl, > ) - #undef DEFINE_CHECK_OP_IMPL - - /* GLOG trick: Function is overloaded for integral types to allow static const integrals - declared in classes and not defined to be used as arguments to CHECK* macros. */ - template - inline const T& referenceable_value(const T& t) { return t; } - inline char referenceable_value(char t) { return t; } - inline unsigned char referenceable_value(unsigned char t) { return t; } - inline signed char referenceable_value(signed char t) { return t; } - inline short referenceable_value(short t) { return t; } - inline unsigned short referenceable_value(unsigned short t) { return t; } - inline int referenceable_value(int t) { return t; } - inline unsigned int referenceable_value(unsigned int t) { return t; } - inline long referenceable_value(long t) { return t; } - inline unsigned long referenceable_value(unsigned long t) { return t; } - inline long long referenceable_value(long long t) { return t; } - inline unsigned long long referenceable_value(unsigned long long t) { return t; } -} // namespace loguru - -// ----------------------------------------------- -// Logging macros: - -// usage: LOG_STREAM(INFO) << "Foo " << std::setprecision(10) << some_value; -#define VLOG_IF_S(verbosity, cond) \ - ((verbosity) > loguru::current_verbosity_cutoff() || (cond) == false) \ - ? (void)0 \ - : loguru::Voidify() & loguru::StreamLogger(verbosity, __FILE__, __LINE__) -#define LOG_IF_S(verbosity_name, cond) VLOG_IF_S(loguru::Verbosity_ ## verbosity_name, cond) -#define VLOG_S(verbosity) VLOG_IF_S(verbosity, true) -#define LOG_S(verbosity_name) VLOG_S(loguru::Verbosity_ ## verbosity_name) - -// ----------------------------------------------- -// ABORT_S macro. Usage: ABORT_S() << "Causo of error: " << details; - -#define ABORT_S() loguru::Voidify() & loguru::AbortLogger("ABORT: ", __FILE__, __LINE__) - -// ----------------------------------------------- -// CHECK_S macros: - -#define CHECK_WITH_INFO_S(cond, info) \ - LOGURU_PREDICT_TRUE((cond) == true) \ - ? (void)0 \ - : loguru::Voidify() & loguru::AbortLogger("CHECK FAILED: " info " ", __FILE__, __LINE__) - -#define CHECK_S(cond) CHECK_WITH_INFO_S(cond, #cond) -#define CHECK_NOTNULL_S(x) CHECK_WITH_INFO_S((x) != nullptr, #x " != nullptr") - -#define CHECK_OP_S(function_name, expr1, op, expr2) \ - while (auto error_string = loguru::function_name(#expr1 " " #op " " #expr2, \ - loguru::referenceable_value(expr1), #op, \ - loguru::referenceable_value(expr2))) \ - loguru::AbortLogger(error_string->c_str(), __FILE__, __LINE__) - -#define CHECK_EQ_S(expr1, expr2) CHECK_OP_S(check_EQ_impl, expr1, ==, expr2) -#define CHECK_NE_S(expr1, expr2) CHECK_OP_S(check_NE_impl, expr1, !=, expr2) -#define CHECK_LE_S(expr1, expr2) CHECK_OP_S(check_LE_impl, expr1, <=, expr2) -#define CHECK_LT_S(expr1, expr2) CHECK_OP_S(check_LT_impl, expr1, < , expr2) -#define CHECK_GE_S(expr1, expr2) CHECK_OP_S(check_GE_impl, expr1, >=, expr2) -#define CHECK_GT_S(expr1, expr2) CHECK_OP_S(check_GT_impl, expr1, > , expr2) - -#if LOGURU_DEBUG_LOGGING - // Debug logging enabled: - #define DVLOG_IF_S(verbosity, cond) VLOG_IF_S(verbosity, cond) - #define DLOG_IF_S(verbosity_name, cond) LOG_IF_S(verbosity_name, cond) - #define DVLOG_S(verbosity) VLOG_S(verbosity) - #define DLOG_S(verbosity_name) LOG_S(verbosity_name) -#else - // Debug logging disabled: - #define DVLOG_IF_S(verbosity, cond) \ - (true || (verbosity) > loguru::current_verbosity_cutoff() || (cond) == false) \ - ? (void)0 \ - : loguru::Voidify() & loguru::StreamLogger(verbosity, __FILE__, __LINE__) - - #define DLOG_IF_S(verbosity_name, cond) DVLOG_IF_S(loguru::Verbosity_ ## verbosity_name, cond) - #define DVLOG_S(verbosity) DVLOG_IF_S(verbosity, true) - #define DLOG_S(verbosity_name) DVLOG_S(loguru::Verbosity_ ## verbosity_name) -#endif - -#if LOGURU_DEBUG_CHECKS - // Debug checks enabled: - #define DCHECK_S(cond) CHECK_S(cond) - #define DCHECK_NOTNULL_S(x) CHECK_NOTNULL_S(x) - #define DCHECK_EQ_S(a, b) CHECK_EQ_S(a, b) - #define DCHECK_NE_S(a, b) CHECK_NE_S(a, b) - #define DCHECK_LT_S(a, b) CHECK_LT_S(a, b) - #define DCHECK_LE_S(a, b) CHECK_LE_S(a, b) - #define DCHECK_GT_S(a, b) CHECK_GT_S(a, b) - #define DCHECK_GE_S(a, b) CHECK_GE_S(a, b) -#else -// Debug checks disabled: - #define DCHECK_S(cond) CHECK_S(true || (cond)) - #define DCHECK_NOTNULL_S(x) CHECK_S(true || (x) != nullptr) - #define DCHECK_EQ_S(a, b) CHECK_S(true || (a) == (b)) - #define DCHECK_NE_S(a, b) CHECK_S(true || (a) != (b)) - #define DCHECK_LT_S(a, b) CHECK_S(true || (a) < (b)) - #define DCHECK_LE_S(a, b) CHECK_S(true || (a) <= (b)) - #define DCHECK_GT_S(a, b) CHECK_S(true || (a) > (b)) - #define DCHECK_GE_S(a, b) CHECK_S(true || (a) >= (b)) -#endif - -#if LOGURU_REPLACE_GLOG - #undef LOG - #undef VLOG - #undef LOG_IF - #undef VLOG_IF - #undef CHECK - #undef CHECK_NOTNULL - #undef CHECK_EQ - #undef CHECK_NE - #undef CHECK_LT - #undef CHECK_LE - #undef CHECK_GT - #undef CHECK_GE - #undef DLOG - #undef DVLOG - #undef DLOG_IF - #undef DVLOG_IF - #undef DCHECK - #undef DCHECK_NOTNULL - #undef DCHECK_EQ - #undef DCHECK_NE - #undef DCHECK_LT - #undef DCHECK_LE - #undef DCHECK_GT - #undef DCHECK_GE - #undef VLOG_IS_ON - - #define LOG LOG_S - #define VLOG VLOG_S - #define LOG_IF LOG_IF_S - #define VLOG_IF VLOG_IF_S - #define CHECK(cond) CHECK_S(!!(cond)) - #define CHECK_NOTNULL CHECK_NOTNULL_S - #define CHECK_EQ CHECK_EQ_S - #define CHECK_NE CHECK_NE_S - #define CHECK_LT CHECK_LT_S - #define CHECK_LE CHECK_LE_S - #define CHECK_GT CHECK_GT_S - #define CHECK_GE CHECK_GE_S - #define DLOG DLOG_S - #define DVLOG DVLOG_S - #define DLOG_IF DLOG_IF_S - #define DVLOG_IF DVLOG_IF_S - #define DCHECK DCHECK_S - #define DCHECK_NOTNULL DCHECK_NOTNULL_S - #define DCHECK_EQ DCHECK_EQ_S - #define DCHECK_NE DCHECK_NE_S - #define DCHECK_LT DCHECK_LT_S - #define DCHECK_LE DCHECK_LE_S - #define DCHECK_GT DCHECK_GT_S - #define DCHECK_GE DCHECK_GE_S - #define VLOG_IS_ON(verbosity) ((verbosity) <= loguru::current_verbosity_cutoff()) - -#endif // LOGURU_REPLACE_GLOG - -#endif // LOGURU_WITH_STREAMS - -#endif // LOGURU_HAS_DECLARED_STREAMS_HEADER \ No newline at end of file diff --git a/libloguru/meson.build b/libloguru/meson.build deleted file mode 100644 index 6c01d58..0000000 --- a/libloguru/meson.build +++ /dev/null @@ -1,20 +0,0 @@ -loguru_inc = [ - include_directories('inc'), -] - -loguru_src = [ - files('src/loguru.cpp'), -] - -loguru_deps = [ - dependency('threads'), - meson.get_compiler('cpp').find_library('dl', required : true), -] - -libloguru = static_library( - 'libloguru', - loguru_src, - dependencies: loguru_deps, - include_directories: loguru_inc, - install:false -) \ No newline at end of file diff --git a/libloguru/src/loguru.cpp b/libloguru/src/loguru.cpp deleted file mode 100644 index 0042789..0000000 --- a/libloguru/src/loguru.cpp +++ /dev/null @@ -1,1795 +0,0 @@ -#ifndef _WIN32 -// Disable all warnings from gcc/clang: -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpragmas" - -#pragma GCC diagnostic ignored "-Wc++98-compat" -#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" -#pragma GCC diagnostic ignored "-Wexit-time-destructors" -#pragma GCC diagnostic ignored "-Wformat-nonliteral" -#pragma GCC diagnostic ignored "-Wglobal-constructors" -#pragma GCC diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" -#pragma GCC diagnostic ignored "-Wmissing-prototypes" -#pragma GCC diagnostic ignored "-Wpadded" -#pragma GCC diagnostic ignored "-Wsign-compare" -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wunknown-pragmas" -#pragma GCC diagnostic ignored "-Wunused-macros" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#endif - -#include - -#ifndef LOGURU_HAS_BEEN_IMPLEMENTED -#define LOGURU_HAS_BEEN_IMPLEMENTED - -#define LOGURU_PREAMBLE_WIDTH (53 + LOGURU_THREADNAME_WIDTH + LOGURU_FILENAME_WIDTH) - -#undef min -#undef max - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 - #include - - #define localtime_r(a, b) localtime_s(b, a) // No localtime_r with MSVC, but arguments are swapped for localtime_s -#else - #include - #include // mkdir - #include // STDERR_FILENO -#endif - -#ifdef __linux__ - #include // PATH_MAX -#elif !defined(_WIN32) - #include // PATH_MAX -#endif - -#ifndef PATH_MAX - #define PATH_MAX 1024 -#endif - -#ifdef __APPLE__ - #include "TargetConditionals.h" -#endif - -// TODO: use defined(_POSIX_VERSION) for some of these things? - -#if defined(_WIN32) || defined(__CYGWIN__) - #define LOGURU_PTHREADS 0 - #define LOGURU_WINTHREADS 1 - #ifndef LOGURU_STACKTRACES - #define LOGURU_STACKTRACES 0 - #endif -#elif defined(__rtems__) || defined(__ANDROID__) - #define LOGURU_PTHREADS 1 - #define LOGURU_WINTHREADS 0 - #ifndef LOGURU_STACKTRACES - #define LOGURU_STACKTRACES 0 - #endif -#else - #define LOGURU_PTHREADS 1 - #define LOGURU_WINTHREADS 0 - #ifndef LOGURU_STACKTRACES - #define LOGURU_STACKTRACES 1 - #endif -#endif - -#if LOGURU_STACKTRACES - #include // for __cxa_demangle - #include // for dladdr - #include // for backtrace -#endif // LOGURU_STACKTRACES - -#if LOGURU_PTHREADS - #include - #if defined(__FreeBSD__) - #include - #include - #elif defined(__OpenBSD__) - #include - #endif - - #ifdef __linux__ - /* On Linux, the default thread name is the same as the name of the binary. - Additionally, all new threads inherit the name of the thread it got forked from. - For this reason, Loguru use the pthread Thread Local Storage - for storing thread names on Linux. */ - #define LOGURU_PTLS_NAMES 1 - #endif -#endif - -#if LOGURU_WINTHREADS - #ifndef _WIN32_WINNT - #define _WIN32_WINNT 0x0502 - #endif - #define WIN32_LEAN_AND_MEAN - #define NOMINMAX - #include -#endif - -#ifndef LOGURU_PTLS_NAMES - #define LOGURU_PTLS_NAMES 0 -#endif - -namespace loguru -{ - using namespace std::chrono; - -#if LOGURU_WITH_FILEABS - struct FileAbs - { - char path[PATH_MAX]; - char mode_str[4]; - Verbosity verbosity; - struct stat st; - FILE* fp; - bool is_reopening = false; // to prevent recursive call in file_reopen. - decltype(steady_clock::now()) last_check_time = steady_clock::now(); - }; -#else - typedef FILE* FileAbs; -#endif - - struct Callback - { - std::string id; - log_handler_t callback; - void* user_data; - Verbosity verbosity; // Does not change! - close_handler_t close; - flush_handler_t flush; - unsigned indentation; - }; - - using CallbackVec = std::vector; - - using StringPair = std::pair; - using StringPairList = std::vector; - - const auto s_start_time = steady_clock::now(); - - Verbosity g_stderr_verbosity = Verbosity_0; - bool g_colorlogtostderr = true; - unsigned g_flush_interval_ms = 0; - bool g_preamble = true; - - Verbosity g_internal_verbosity = Verbosity_0; - - // Preamble details - bool g_preamble_date = true; - bool g_preamble_time = true; - bool g_preamble_uptime = true; - bool g_preamble_thread = true; - bool g_preamble_file = true; - bool g_preamble_verbose = true; - bool g_preamble_pipe = true; - - static std::recursive_mutex s_mutex; - static Verbosity s_max_out_verbosity = Verbosity_OFF; - static std::string s_argv0_filename; - static std::string s_arguments; - static char s_current_dir[PATH_MAX]; - static CallbackVec s_callbacks; - static fatal_handler_t s_fatal_handler = nullptr; - static verbosity_to_name_t s_verbosity_to_name_callback = nullptr; - static name_to_verbosity_t s_name_to_verbosity_callback = nullptr; - static StringPairList s_user_stack_cleanups; - static bool s_strip_file_path = true; - static std::atomic s_stderr_indentation { 0 }; - - // For periodic flushing: - static std::thread* s_flush_thread = nullptr; - static bool s_needs_flushing = false; - - static const bool s_terminal_has_color = [](){ - #ifdef _WIN32 - #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING - #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 - #endif - - HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); - if (hOut != INVALID_HANDLE_VALUE) { - DWORD dwMode = 0; - GetConsoleMode(hOut, &dwMode); - dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - return SetConsoleMode(hOut, dwMode) != 0; - } - return false; - #else - if (const char* term = getenv("TERM")) { - return 0 == strcmp(term, "cygwin") - || 0 == strcmp(term, "linux") - || 0 == strcmp(term, "rxvt-unicode-256color") - || 0 == strcmp(term, "screen") - || 0 == strcmp(term, "screen-256color") - || 0 == strcmp(term, "screen.xterm-256color") - || 0 == strcmp(term, "tmux-256color") - || 0 == strcmp(term, "xterm") - || 0 == strcmp(term, "xterm-256color") - || 0 == strcmp(term, "xterm-termite") - || 0 == strcmp(term, "xterm-color"); - } else { - return false; - } - #endif - }(); - - static void print_preamble_header(char* out_buff, size_t out_buff_size); - - #if LOGURU_PTLS_NAMES - static pthread_once_t s_pthread_key_once = PTHREAD_ONCE_INIT; - static pthread_key_t s_pthread_key_name; - - void make_pthread_key_name() - { - (void)pthread_key_create(&s_pthread_key_name, free); - } - #endif - - // ------------------------------------------------------------------------------ - // Colors - - bool terminal_has_color() { return s_terminal_has_color; } - - // Colors - -#ifdef _WIN32 -#define VTSEQ(ID) ("\x1b[1;" #ID "m") -#else -#define VTSEQ(ID) ("\x1b[" #ID "m") -#endif - - const char* terminal_black() { return s_terminal_has_color ? VTSEQ(30) : ""; } - const char* terminal_red() { return s_terminal_has_color ? VTSEQ(31) : ""; } - const char* terminal_green() { return s_terminal_has_color ? VTSEQ(32) : ""; } - const char* terminal_yellow() { return s_terminal_has_color ? VTSEQ(33) : ""; } - const char* terminal_blue() { return s_terminal_has_color ? VTSEQ(34) : ""; } - const char* terminal_purple() { return s_terminal_has_color ? VTSEQ(35) : ""; } - const char* terminal_cyan() { return s_terminal_has_color ? VTSEQ(36) : ""; } - const char* terminal_light_gray() { return s_terminal_has_color ? VTSEQ(37) : ""; } - const char* terminal_white() { return s_terminal_has_color ? VTSEQ(37) : ""; } - const char* terminal_light_red() { return s_terminal_has_color ? VTSEQ(91) : ""; } - const char* terminal_dim() { return s_terminal_has_color ? VTSEQ(2) : ""; } - - // Formating - const char* terminal_bold() { return s_terminal_has_color ? VTSEQ(1) : ""; } - const char* terminal_underline() { return s_terminal_has_color ? VTSEQ(4) : ""; } - - // You should end each line with this! - const char* terminal_reset() { return s_terminal_has_color ? VTSEQ(0) : ""; } - - // ------------------------------------------------------------------------------ -#if LOGURU_WITH_FILEABS - void file_reopen(void* user_data); - inline FILE* to_file(void* user_data) { return reinterpret_cast(user_data)->fp; } -#else - inline FILE* to_file(void* user_data) { return reinterpret_cast(user_data); } -#endif - - void file_log(void* user_data, const Message& message) - { -#if LOGURU_WITH_FILEABS - FileAbs* file_abs = reinterpret_cast(user_data); - if (file_abs->is_reopening) { - return; - } - // It is better checking file change every minute/hour/day, - // instead of doing this every time we log. - // Here check_interval is set to zero to enable checking every time; - const auto check_interval = seconds(0); - if (duration_cast(steady_clock::now() - file_abs->last_check_time) > check_interval) { - file_abs->last_check_time = steady_clock::now(); - file_reopen(user_data); - } - FILE* file = to_file(user_data); - if (!file) { - return; - } -#else - FILE* file = to_file(user_data); -#endif - fprintf(file, "%s%s%s%s\n", - message.preamble, message.indentation, message.prefix, message.message); - if (g_flush_interval_ms == 0) { - fflush(file); - } - } - - void file_close(void* user_data) - { - FILE* file = to_file(user_data); - if (file) { - fclose(file); - } -#if LOGURU_WITH_FILEABS - delete reinterpret_cast(user_data); -#endif - } - - void file_flush(void* user_data) - { - FILE* file = to_file(user_data); - fflush(file); - } - -#if LOGURU_WITH_FILEABS - void file_reopen(void* user_data) - { - FileAbs * file_abs = reinterpret_cast(user_data); - struct stat st; - int ret; - if (!file_abs->fp || (ret = stat(file_abs->path, &st)) == -1 || (st.st_ino != file_abs->st.st_ino)) { - file_abs->is_reopening = true; - if (file_abs->fp) { - fclose(file_abs->fp); - } - if (!file_abs->fp) { - VLOG_F(g_internal_verbosity, "Reopening file '%s' due to previous error", file_abs->path); - } - else if (ret < 0) { - const auto why = errno_as_text(); - VLOG_F(g_internal_verbosity, "Reopening file '%s' due to '%s'", file_abs->path, why.c_str()); - } else { - VLOG_F(g_internal_verbosity, "Reopening file '%s' due to file changed", file_abs->path); - } - // try reopen current file. - if (!create_directories(file_abs->path)) { - LOG_F(ERROR, "Failed to create directories to '%s'", file_abs->path); - } - file_abs->fp = fopen(file_abs->path, file_abs->mode_str); - if (!file_abs->fp) { - LOG_F(ERROR, "Failed to open '%s'", file_abs->path); - } else { - stat(file_abs->path, &file_abs->st); - } - file_abs->is_reopening = false; - } - } -#endif - // ------------------------------------------------------------------------------ - - // Helpers: - - Text::~Text() { free(_str); } - - LOGURU_PRINTF_LIKE(1, 0) - static Text vtextprintf(const char* format, va_list vlist) - { -#ifdef _WIN32 - int bytes_needed = _vscprintf(format, vlist); - CHECK_F(bytes_needed >= 0, "Bad string format: '%s'", format); - char* buff = (char*)malloc(bytes_needed+1); - vsnprintf(buff, bytes_needed+1, format, vlist); - return Text(buff); -#else - char* buff = nullptr; - int result = vasprintf(&buff, format, vlist); - CHECK_F(result >= 0, "Bad string format: '%s'", format); - return Text(buff); -#endif - } - - Text textprintf(const char* format, ...) - { - va_list vlist; - va_start(vlist, format); - auto result = vtextprintf(format, vlist); - va_end(vlist); - return result; - } - - // Overloaded for variadic template matching. - Text textprintf() - { - return Text(static_cast(calloc(1, 1))); - } - - static const char* indentation(unsigned depth) - { - static const char buff[] = - ". . . . . . . . . . " ". . . . . . . . . . " - ". . . . . . . . . . " ". . . . . . . . . . " - ". . . . . . . . . . " ". . . . . . . . . . " - ". . . . . . . . . . " ". . . . . . . . . . " - ". . . . . . . . . . " ". . . . . . . . . . "; - static const size_t INDENTATION_WIDTH = 4; - static const size_t NUM_INDENTATIONS = (sizeof(buff) - 1) / INDENTATION_WIDTH; - depth = std::min(depth, NUM_INDENTATIONS); - return buff + INDENTATION_WIDTH * (NUM_INDENTATIONS - depth); - } - - static void parse_args(int& argc, char* argv[], const char* verbosity_flag) - { - int arg_dest = 1; - int out_argc = argc; - - for (int arg_it = 1; arg_it < argc; ++arg_it) { - auto cmd = argv[arg_it]; - auto arg_len = strlen(verbosity_flag); - if (strncmp(cmd, verbosity_flag, arg_len) == 0 && !std::isalpha(cmd[arg_len], std::locale(""))) { - out_argc -= 1; - auto value_str = cmd + arg_len; - if (value_str[0] == '\0') { - // Value in separate argument - arg_it += 1; - CHECK_LT_F(arg_it, argc, "Missing verbosiy level after %s", verbosity_flag); - value_str = argv[arg_it]; - out_argc -= 1; - } - if (*value_str == '=') { value_str += 1; } - - auto req_verbosity = get_verbosity_from_name(value_str); - if (req_verbosity != Verbosity_INVALID) { - g_stderr_verbosity = req_verbosity; - } else { - char* end = 0; - g_stderr_verbosity = static_cast(strtol(value_str, &end, 10)); - CHECK_F(end && *end == '\0', - "Invalid verbosity. Expected integer, INFO, WARNING, ERROR or OFF, got '%s'", value_str); - } - } else { - argv[arg_dest++] = argv[arg_it]; - } - } - - argc = out_argc; - argv[argc] = nullptr; - } - - static long long now_ns() - { - return duration_cast(high_resolution_clock::now().time_since_epoch()).count(); - } - - // Returns the part of the path after the last / or \ (if any). - const char* filename(const char* path) - { - for (auto ptr = path; *ptr; ++ptr) { - if (*ptr == '/' || *ptr == '\\') { - path = ptr + 1; - } - } - return path; - } - - // ------------------------------------------------------------------------------ - - static void on_atexit() - { - VLOG_F(g_internal_verbosity, "atexit"); - flush(); - } - - static void install_signal_handlers(); - - static void write_hex_digit(std::string& out, unsigned num) - { - DCHECK_LT_F(num, 16u); - if (num < 10u) { out.push_back(char('0' + num)); } - else { out.push_back(char('A' + num - 10)); } - } - - static void write_hex_byte(std::string& out, uint8_t n) - { - write_hex_digit(out, n >> 4u); - write_hex_digit(out, n & 0x0f); - } - - static void escape(std::string& out, const std::string& str) - { - for (char c : str) { - /**/ if (c == '\a') { out += "\\a"; } - else if (c == '\b') { out += "\\b"; } - else if (c == '\f') { out += "\\f"; } - else if (c == '\n') { out += "\\n"; } - else if (c == '\r') { out += "\\r"; } - else if (c == '\t') { out += "\\t"; } - else if (c == '\v') { out += "\\v"; } - else if (c == '\\') { out += "\\\\"; } - else if (c == '\'') { out += "\\\'"; } - else if (c == '\"') { out += "\\\""; } - else if (c == ' ') { out += "\\ "; } - else if (0 <= c && c < 0x20) { // ASCI control character: - // else if (c < 0x20 || c != (c & 127)) { // ASCII control character or UTF-8: - out += "\\x"; - write_hex_byte(out, static_cast(c)); - } else { out += c; } - } - } - - Text errno_as_text() - { - char buff[256]; - #if defined(__GLIBC__) && defined(_GNU_SOURCE) - // GNU Version - return Text(STRDUP(strerror_r(errno, buff, sizeof(buff)))); - #elif defined(__APPLE__) || _POSIX_C_SOURCE >= 200112L - // XSI Version - strerror_r(errno, buff, sizeof(buff)); - return Text(strdup(buff)); - #elif defined(_WIN32) - strerror_s(buff, sizeof(buff), errno); - return Text(STRDUP(buff)); - #else - // Not thread-safe. - return Text(STRDUP(strerror(errno))); - #endif - } - - void init(int& argc, char* argv[], const char* verbosity_flag) - { - CHECK_GT_F(argc, 0, "Expected proper argc/argv"); - CHECK_EQ_F(argv[argc], nullptr, "Expected proper argc/argv"); - - s_argv0_filename = filename(argv[0]); - - #ifdef _WIN32 - #define getcwd _getcwd - #endif - - if (!getcwd(s_current_dir, sizeof(s_current_dir))) - { - const auto error_text = errno_as_text(); - LOG_F(WARNING, "Failed to get current working directory: %s", error_text.c_str()); - } - - s_arguments = ""; - for (int i = 0; i < argc; ++i) { - escape(s_arguments, argv[i]); - if (i + 1 < argc) { - s_arguments += " "; - } - } - - if (verbosity_flag) { - parse_args(argc, argv, verbosity_flag); - } - - #if LOGURU_PTLS_NAMES || LOGURU_WINTHREADS - set_thread_name("main thread"); - #elif LOGURU_PTHREADS - char old_thread_name[16] = {0}; - auto this_thread = pthread_self(); - #if defined(__APPLE__) || defined(__linux__) - pthread_getname_np(this_thread, old_thread_name, sizeof(old_thread_name)); - #endif - if (old_thread_name[0] == 0) { - #ifdef __APPLE__ - pthread_setname_np("main thread"); - #elif defined(__FreeBSD__) || defined(__OpenBSD__) - pthread_set_name_np(this_thread, "main thread"); - #elif defined(__linux__) - pthread_setname_np(this_thread, "main thread"); - #endif - } - #endif // LOGURU_PTHREADS - - if (g_stderr_verbosity >= Verbosity_INFO) { - if (g_preamble) { - char preamble_explain[LOGURU_PREAMBLE_WIDTH]; - print_preamble_header(preamble_explain, sizeof(preamble_explain)); - if (g_colorlogtostderr && s_terminal_has_color) { - fprintf(stderr, "%s%s%s\n", terminal_reset(), terminal_dim(), preamble_explain); - } else { - fprintf(stderr, "%s\n", preamble_explain); - } - } - fflush(stderr); - } - VLOG_F(g_internal_verbosity, "arguments: %s", s_arguments.c_str()); - if (strlen(s_current_dir) != 0) - { - VLOG_F(g_internal_verbosity, "Current dir: %s", s_current_dir); - } - VLOG_F(g_internal_verbosity, "stderr verbosity: %d", g_stderr_verbosity); - VLOG_F(g_internal_verbosity, "-----------------------------------"); - - install_signal_handlers(); - - atexit(on_atexit); - } - - void shutdown() - { - VLOG_F(g_internal_verbosity, "loguru::shutdown()"); - remove_all_callbacks(); - set_fatal_handler(nullptr); - set_verbosity_to_name_callback(nullptr); - set_name_to_verbosity_callback(nullptr); - } - - void write_date_time(char* buff, size_t buff_size) - { - auto now = system_clock::now(); - long long ms_since_epoch = duration_cast(now.time_since_epoch()).count(); - time_t sec_since_epoch = time_t(ms_since_epoch / 1000); - tm time_info; - localtime_r(&sec_since_epoch, &time_info); - snprintf(buff, buff_size, "%04d%02d%02d_%02d%02d%02d.%03lld", - 1900 + time_info.tm_year, 1 + time_info.tm_mon, time_info.tm_mday, - time_info.tm_hour, time_info.tm_min, time_info.tm_sec, ms_since_epoch % 1000); - } - - const char* argv0_filename() - { - return s_argv0_filename.c_str(); - } - - const char* arguments() - { - return s_arguments.c_str(); - } - - const char* current_dir() - { - return s_current_dir; - } - - const char* home_dir() - { - #ifdef _WIN32 - auto user_profile = getenv("USERPROFILE"); - CHECK_F(user_profile != nullptr, "Missing USERPROFILE"); - return user_profile; - #else // _WIN32 - auto home = getenv("HOME"); - CHECK_F(home != nullptr, "Missing HOME"); - return home; - #endif // _WIN32 - } - - void suggest_log_path(const char* prefix, char* buff, unsigned buff_size) - { - if (prefix[0] == '~') { - snprintf(buff, buff_size - 1, "%s%s", home_dir(), prefix + 1); - } else { - snprintf(buff, buff_size - 1, "%s", prefix); - } - - // Check for terminating / - size_t n = strlen(buff); - if (n != 0) { - if (buff[n - 1] != '/') { - CHECK_F(n + 2 < buff_size, "Filename buffer too small"); - buff[n] = '/'; - buff[n + 1] = '\0'; - } - } - - strncat(buff, s_argv0_filename.c_str(), buff_size - strlen(buff) - 1); - strncat(buff, "/", buff_size - strlen(buff) - 1); - write_date_time(buff + strlen(buff), buff_size - strlen(buff)); - strncat(buff, ".log", buff_size - strlen(buff) - 1); - } - - bool create_directories(const char* file_path_const) - { - CHECK_F(file_path_const && *file_path_const); - char* file_path = STRDUP(file_path_const); - for (char* p = strchr(file_path + 1, '/'); p; p = strchr(p + 1, '/')) { - *p = '\0'; - - #ifdef _WIN32 - if (_mkdir(file_path) == -1) { - #else - if (mkdir(file_path, 0755) == -1) { - #endif - if (errno != EEXIST) { - LOG_F(ERROR, "Failed to create directory '%s'", file_path); - LOG_IF_F(ERROR, errno == EACCES, "EACCES"); - LOG_IF_F(ERROR, errno == ENAMETOOLONG, "ENAMETOOLONG"); - LOG_IF_F(ERROR, errno == ENOENT, "ENOENT"); - LOG_IF_F(ERROR, errno == ENOTDIR, "ENOTDIR"); - LOG_IF_F(ERROR, errno == ELOOP, "ELOOP"); - - *p = '/'; - free(file_path); - return false; - } - } - *p = '/'; - } - free(file_path); - return true; - } - bool add_file(const char* path_in, FileMode mode, Verbosity verbosity) - { - char path[PATH_MAX]; - if (path_in[0] == '~') { - snprintf(path, sizeof(path) - 1, "%s%s", home_dir(), path_in + 1); - } else { - snprintf(path, sizeof(path) - 1, "%s", path_in); - } - - if (!create_directories(path)) { - LOG_F(ERROR, "Failed to create directories to '%s'", path); - } - - const char* mode_str = (mode == FileMode::Truncate ? "w" : "a"); - auto file = fopen(path, mode_str); - if (!file) { - LOG_F(ERROR, "Failed to open '%s'", path); - return false; - } -#if LOGURU_WITH_FILEABS - FileAbs* file_abs = new FileAbs(); // this is deleted in file_close; - snprintf(file_abs->path, sizeof(file_abs->path) - 1, "%s", path); - snprintf(file_abs->mode_str, sizeof(file_abs->mode_str) - 1, "%s", mode_str); - stat(file_abs->path, &file_abs->st); - file_abs->fp = file; - file_abs->verbosity = verbosity; - add_callback(path_in, file_log, file_abs, verbosity, file_close, file_flush); -#else - add_callback(path_in, file_log, file, verbosity, file_close, file_flush); -#endif - - if (mode == FileMode::Append) { - fprintf(file, "\n\n\n\n\n"); - } - if (!s_arguments.empty()) { - fprintf(file, "arguments: %s\n", s_arguments.c_str()); - } - if (strlen(s_current_dir) != 0) { - fprintf(file, "Current dir: %s\n", s_current_dir); - } - fprintf(file, "File verbosity level: %d\n", verbosity); - if (g_preamble) { - char preamble_explain[LOGURU_PREAMBLE_WIDTH]; - print_preamble_header(preamble_explain, sizeof(preamble_explain)); - fprintf(file, "%s\n", preamble_explain); - } - fflush(file); - - VLOG_F(g_internal_verbosity, "Logging to '%s', mode: '%s', verbosity: %d", path, mode_str, verbosity); - return true; - } - - // Will be called right before abort(). - void set_fatal_handler(fatal_handler_t handler) - { - s_fatal_handler = handler; - } - - fatal_handler_t get_fatal_handler() - { - return s_fatal_handler; - } - - void set_verbosity_to_name_callback(verbosity_to_name_t callback) - { - s_verbosity_to_name_callback = callback; - } - - void set_name_to_verbosity_callback(name_to_verbosity_t callback) - { - s_name_to_verbosity_callback = callback; - } - - void add_stack_cleanup(const char* find_this, const char* replace_with_this) - { - if (strlen(find_this) <= strlen(replace_with_this)) { - LOG_F(WARNING, "add_stack_cleanup: the replacement should be shorter than the pattern!"); - return; - } - - s_user_stack_cleanups.push_back(StringPair(find_this, replace_with_this)); - } - - static void on_callback_change() - { - s_max_out_verbosity = Verbosity_OFF; - for (const auto& callback : s_callbacks) { - s_max_out_verbosity = std::max(s_max_out_verbosity, callback.verbosity); - } - } - - void add_callback( - const char* id, - log_handler_t callback, - void* user_data, - Verbosity verbosity, - close_handler_t on_close, - flush_handler_t on_flush) - { - std::lock_guard lock(s_mutex); - s_callbacks.push_back(Callback{id, callback, user_data, verbosity, on_close, on_flush, 0}); - on_callback_change(); - } - - // Returns a custom verbosity name if one is available, or nullptr. - // See also set_verbosity_to_name_callback. - const char* get_verbosity_name(Verbosity verbosity) - { - auto name = s_verbosity_to_name_callback - ? (*s_verbosity_to_name_callback)(verbosity) - : nullptr; - - // Use standard replacements if callback fails: - if (!name) - { - if (verbosity <= Verbosity_FATAL) { - name = "FATL"; - } else if (verbosity == Verbosity_ERROR) { - name = "ERR"; - } else if (verbosity == Verbosity_WARNING) { - name = "WARN"; - } else if (verbosity == Verbosity_INFO) { - name = "INFO"; - } - } - - return name; - } - - // Returns Verbosity_INVALID if the name is not found. - // See also set_name_to_verbosity_callback. - Verbosity get_verbosity_from_name(const char* name) - { - auto verbosity = s_name_to_verbosity_callback - ? (*s_name_to_verbosity_callback)(name) - : Verbosity_INVALID; - - // Use standard replacements if callback fails: - if (verbosity == Verbosity_INVALID) { - if (strcmp(name, "OFF") == 0) { - verbosity = Verbosity_OFF; - } else if (strcmp(name, "INFO") == 0) { - verbosity = Verbosity_INFO; - } else if (strcmp(name, "WARNING") == 0) { - verbosity = Verbosity_WARNING; - } else if (strcmp(name, "ERROR") == 0) { - verbosity = Verbosity_ERROR; - } else if (strcmp(name, "FATAL") == 0) { - verbosity = Verbosity_FATAL; - } - } - - return verbosity; - } - - bool remove_callback(const char* id) - { - std::lock_guard lock(s_mutex); - auto it = std::find_if(begin(s_callbacks), end(s_callbacks), [&](const Callback& c) { return c.id == id; }); - if (it != s_callbacks.end()) { - if (it->close) { it->close(it->user_data); } - s_callbacks.erase(it); - on_callback_change(); - return true; - } else { - LOG_F(ERROR, "Failed to locate callback with id '%s'", id); - return false; - } - } - - void remove_all_callbacks() - { - std::lock_guard lock(s_mutex); - for (auto& callback : s_callbacks) { - if (callback.close) { - callback.close(callback.user_data); - } - } - s_callbacks.clear(); - on_callback_change(); - } - - // Returns the maximum of g_stderr_verbosity and all file/custom outputs. - Verbosity current_verbosity_cutoff() - { - return g_stderr_verbosity > s_max_out_verbosity ? - g_stderr_verbosity : s_max_out_verbosity; - } - -#if LOGURU_WINTHREADS - char* get_thread_name_win32() - { - __declspec( thread ) static char thread_name[LOGURU_THREADNAME_WIDTH + 1] = {0}; - return &thread_name[0]; - } -#endif // LOGURU_WINTHREADS - - void set_thread_name(const char* name) - { - #if LOGURU_PTLS_NAMES - (void)pthread_once(&s_pthread_key_once, make_pthread_key_name); - (void)pthread_setspecific(s_pthread_key_name, STRDUP(name)); - - #elif LOGURU_PTHREADS - #ifdef __APPLE__ - pthread_setname_np(name); - #elif defined(__FreeBSD__) || defined(__OpenBSD__) - pthread_set_name_np(pthread_self(), name); - #elif defined(__linux__) - pthread_setname_np(pthread_self(), name); - #endif - #elif LOGURU_WINTHREADS - strncpy_s(get_thread_name_win32(), LOGURU_THREADNAME_WIDTH + 1, name, _TRUNCATE); - #else // LOGURU_PTHREADS - (void)name; - #endif // LOGURU_PTHREADS - } - -#if LOGURU_PTLS_NAMES - const char* get_thread_name_ptls() - { - (void)pthread_once(&s_pthread_key_once, make_pthread_key_name); - return static_cast(pthread_getspecific(s_pthread_key_name)); - } -#endif // LOGURU_PTLS_NAMES - - void get_thread_name(char* buffer, unsigned long long length, bool right_align_hext_id) - { -#ifdef _WIN32 - (void)right_align_hext_id; -#endif - CHECK_NE_F(length, 0u, "Zero length buffer in get_thread_name"); - CHECK_NOTNULL_F(buffer, "nullptr in get_thread_name"); -#if LOGURU_PTHREADS - auto thread = pthread_self(); - #if LOGURU_PTLS_NAMES - if (const char* name = get_thread_name_ptls()) { - snprintf(buffer, length, "%s", name); - } else { - buffer[0] = 0; - } - #elif defined(__APPLE__) || defined(__linux__) - pthread_getname_np(thread, buffer, length); - #else - buffer[0] = 0; - #endif - - if (buffer[0] == 0) { - #ifdef __APPLE__ - uint64_t thread_id; - pthread_threadid_np(thread, &thread_id); - #elif defined(__FreeBSD__) - long thread_id; - (void)thr_self(&thread_id); - #elif defined(__OpenBSD__) - unsigned thread_id = -1; - #else - uint64_t thread_id = thread; - #endif - if (right_align_hext_id) { - snprintf(buffer, length, "%*X", static_cast(length - 1), static_cast(thread_id)); - } else { - snprintf(buffer, length, "%X", static_cast(thread_id)); - } - } -#elif LOGURU_WINTHREADS - if (const char* name = get_thread_name_win32()) { - snprintf(buffer, (size_t)length, "%s", name); - } else { - buffer[0] = 0; - } -#else // !LOGURU_WINTHREADS && !LOGURU_WINTHREADS - buffer[0] = 0; -#endif - - } - - // ------------------------------------------------------------------------ - // Stack traces - -#if LOGURU_STACKTRACES - Text demangle(const char* name) - { - int status = -1; - char* demangled = abi::__cxa_demangle(name, 0, 0, &status); - Text result{status == 0 ? demangled : STRDUP(name)}; - return result; - } - - #if LOGURU_RTTI - template - std::string type_name() - { - auto demangled = demangle(typeid(T).name()); - return demangled.c_str(); - } - #endif // LOGURU_RTTI - - static const StringPairList REPLACE_LIST = { - #if LOGURU_RTTI - { type_name(), "std::string" }, - { type_name(), "std::wstring" }, - { type_name(), "std::u16string" }, - { type_name(), "std::u32string" }, - #endif // LOGURU_RTTI - { "std::__1::", "std::" }, - { "__thiscall ", "" }, - { "__cdecl ", "" }, - }; - - void do_replacements(const StringPairList& replacements, std::string& str) - { - for (auto&& p : replacements) { - if (p.first.size() <= p.second.size()) { - // On gcc, "type_name()" is "std::string" - continue; - } - - size_t it; - while ((it=str.find(p.first)) != std::string::npos) { - str.replace(it, p.first.size(), p.second); - } - } - } - - std::string prettify_stacktrace(const std::string& input) - { - std::string output = input; - - do_replacements(s_user_stack_cleanups, output); - do_replacements(REPLACE_LIST, output); - - try { - std::regex std_allocator_re(R"(,\s*std::allocator<[^<>]+>)"); - output = std::regex_replace(output, std_allocator_re, std::string("")); - - std::regex template_spaces_re(R"(<\s*([^<> ]+)\s*>)"); - output = std::regex_replace(output, template_spaces_re, std::string("<$1>")); - } catch (std::regex_error&) { - // Probably old GCC. - } - - return output; - } - - std::string stacktrace_as_stdstring(int skip) - { - // From https://gist.github.com/fmela/591333 - void* callstack[128] = {0}; - const auto max_frames = sizeof(callstack) / sizeof(callstack[0]); - int num_frames = backtrace(callstack, max_frames); - char** symbols = backtrace_symbols(callstack, num_frames); - - std::string result; - // Print stack traces so the most relevant ones are written last - // Rationale: http://yellerapp.com/posts/2015-01-22-upside-down-stacktraces.html - for (int i = num_frames - 1; i >= skip; --i) { - char buf[1024]; - Dl_info info; - if (dladdr(callstack[i], &info) && info.dli_sname) { - char* demangled = NULL; - int status = -1; - if (info.dli_sname[0] == '_') { - demangled = abi::__cxa_demangle(info.dli_sname, 0, 0, &status); - } - snprintf(buf, sizeof(buf), "%-3d %*p %s + %zd\n", - i - skip, int(2 + sizeof(void*) * 2), callstack[i], - status == 0 ? demangled : - info.dli_sname == 0 ? symbols[i] : info.dli_sname, - static_cast(callstack[i]) - static_cast(info.dli_saddr)); - free(demangled); - } else { - snprintf(buf, sizeof(buf), "%-3d %*p %s\n", - i - skip, int(2 + sizeof(void*) * 2), callstack[i], symbols[i]); - } - result += buf; - } - free(symbols); - - if (num_frames == max_frames) { - result = "[truncated]\n" + result; - } - - if (!result.empty() && result[result.size() - 1] == '\n') { - result.resize(result.size() - 1); - } - - return prettify_stacktrace(result); - } - -#else // LOGURU_STACKTRACES - Text demangle(const char* name) - { - return Text(STRDUP(name)); - } - - std::string stacktrace_as_stdstring(int) - { - // No stacktraces available on this platform" - return ""; - } - -#endif // LOGURU_STACKTRACES - - Text stacktrace(int skip) - { - auto str = stacktrace_as_stdstring(skip + 1); - return Text(STRDUP(str.c_str())); - } - - // ------------------------------------------------------------------------ - - static void print_preamble_header(char* out_buff, size_t out_buff_size) - { - if (out_buff_size == 0) { return; } - out_buff[0] = '\0'; - long pos = 0; - if (g_preamble_date && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "date "); - } - if (g_preamble_time && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "time "); - } - if (g_preamble_uptime && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "( uptime ) "); - } - if (g_preamble_thread && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "[%-*s]", LOGURU_THREADNAME_WIDTH, " thread name/id"); - } - if (g_preamble_file && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "%*s:line ", LOGURU_FILENAME_WIDTH, "file"); - } - if (g_preamble_verbose && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, " v"); - } - if (g_preamble_pipe && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "| "); - } - } - - static void print_preamble(char* out_buff, size_t out_buff_size, Verbosity verbosity, const char* file, unsigned line) - { - if (out_buff_size == 0) { return; } - out_buff[0] = '\0'; - if (!g_preamble) { return; } - long long ms_since_epoch = duration_cast(system_clock::now().time_since_epoch()).count(); - time_t sec_since_epoch = time_t(ms_since_epoch / 1000); - tm time_info; - localtime_r(&sec_since_epoch, &time_info); - - auto uptime_ms = duration_cast(steady_clock::now() - s_start_time).count(); - auto uptime_sec = uptime_ms / 1000.0; - - char thread_name[LOGURU_THREADNAME_WIDTH + 1] = {0}; - get_thread_name(thread_name, LOGURU_THREADNAME_WIDTH + 1, true); - - if (s_strip_file_path) { - file = filename(file); - } - - char level_buff[6]; - const char* custom_level_name = get_verbosity_name(verbosity); - if (custom_level_name) { - snprintf(level_buff, sizeof(level_buff) - 1, "%s", custom_level_name); - } else { - snprintf(level_buff, sizeof(level_buff) - 1, "% 4d", verbosity); - } - - long pos = 0; - - if (g_preamble_date && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "%04d-%02d-%02d ", - 1900 + time_info.tm_year, 1 + time_info.tm_mon, time_info.tm_mday); - } - if (g_preamble_time && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "%02d:%02d:%02d.%03lld ", - time_info.tm_hour, time_info.tm_min, time_info.tm_sec, ms_since_epoch % 1000); - } - if (g_preamble_uptime && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "(%8.3fs) ", - uptime_sec); - } - if (g_preamble_thread && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "[%-*s]", - LOGURU_THREADNAME_WIDTH, thread_name); - } - if (g_preamble_file && pos < out_buff_size) { - char shortened_filename[LOGURU_FILENAME_WIDTH + 1]; - snprintf(shortened_filename, LOGURU_FILENAME_WIDTH + 1, "%s", file); - pos += snprintf(out_buff + pos, out_buff_size - pos, "%*s:%-5u ", - LOGURU_FILENAME_WIDTH, shortened_filename, line); - } - if (g_preamble_verbose && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "%4s", - level_buff); - } - if (g_preamble_pipe && pos < out_buff_size) { - pos += snprintf(out_buff + pos, out_buff_size - pos, "| "); - } - } - - // stack_trace_skip is just if verbosity == FATAL. - static void log_message(int stack_trace_skip, Message& message, bool with_indentation, bool abort_if_fatal) - { - const auto verbosity = message.verbosity; - std::lock_guard lock(s_mutex); - - if (message.verbosity == Verbosity_FATAL) { - auto st = loguru::stacktrace(stack_trace_skip + 2); - if (!st.empty()) { - RAW_LOG_F(ERROR, "Stack trace:\n%s", st.c_str()); - } - - auto ec = loguru::get_error_context(); - if (!ec.empty()) { - RAW_LOG_F(ERROR, "%s", ec.c_str()); - } - } - - if (with_indentation) { - message.indentation = indentation(s_stderr_indentation); - } - - if (verbosity <= g_stderr_verbosity) { - if (g_colorlogtostderr && s_terminal_has_color) { - if (verbosity > Verbosity_WARNING) { - fprintf(stderr, "%s%s%s%s%s%s%s%s\n", - terminal_reset(), - terminal_dim(), - message.preamble, - message.indentation, - verbosity == Verbosity_INFO ? terminal_reset() : "", // un-dim for info - message.prefix, - message.message, - terminal_reset()); - } else { - fprintf(stderr, "%s%s%s%s%s%s%s\n", - terminal_reset(), - verbosity == Verbosity_WARNING ? terminal_yellow() : terminal_red(), - message.preamble, - message.indentation, - message.prefix, - message.message, - terminal_reset()); - } - } else { - fprintf(stderr, "%s%s%s%s\n", - message.preamble, message.indentation, message.prefix, message.message); - } - - if (g_flush_interval_ms == 0) { - fflush(stderr); - } else { - s_needs_flushing = true; - } - } - - for (auto& p : s_callbacks) { - if (verbosity <= p.verbosity) { - if (with_indentation) { - message.indentation = indentation(p.indentation); - } - p.callback(p.user_data, message); - if (g_flush_interval_ms == 0) { - if (p.flush) { p.flush(p.user_data); } - } else { - s_needs_flushing = true; - } - } - } - - if (g_flush_interval_ms > 0 && !s_flush_thread) { - s_flush_thread = new std::thread([](){ - for (;;) { - if (s_needs_flushing) { - flush(); - } - std::this_thread::sleep_for(std::chrono::milliseconds(g_flush_interval_ms)); - } - }); - } - - if (message.verbosity == Verbosity_FATAL) { - flush(); - - if (s_fatal_handler) { - s_fatal_handler(message); - flush(); - } - - if (abort_if_fatal) { -#if LOGURU_CATCH_SIGABRT && !defined(_WIN32) - // Make sure we don't catch our own abort: - signal(SIGABRT, SIG_DFL); -#endif - abort(); - } - } - } - - // stack_trace_skip is just if verbosity == FATAL. - void log_to_everywhere(int stack_trace_skip, Verbosity verbosity, - const char* file, unsigned line, - const char* prefix, const char* buff) - { - char preamble_buff[LOGURU_PREAMBLE_WIDTH]; - print_preamble(preamble_buff, sizeof(preamble_buff), verbosity, file, line); - auto message = Message{verbosity, file, line, preamble_buff, "", prefix, buff}; - log_message(stack_trace_skip + 1, message, true, true); - } - -#if LOGURU_USE_FMTLIB - void log(Verbosity verbosity, const char* file, unsigned line, const char* format, fmt::ArgList args) - { - auto formatted = fmt::format(format, args); - log_to_everywhere(1, verbosity, file, line, "", formatted.c_str()); - } - - void raw_log(Verbosity verbosity, const char* file, unsigned line, const char* format, fmt::ArgList args) - { - auto formatted = fmt::format(format, args); - auto message = Message{verbosity, file, line, "", "", "", formatted.c_str()}; - log_message(1, message, false, true); - } - -#else - void log(Verbosity verbosity, const char* file, unsigned line, const char* format, ...) - { - va_list vlist; - va_start(vlist, format); - auto buff = vtextprintf(format, vlist); - log_to_everywhere(1, verbosity, file, line, "", buff.c_str()); - va_end(vlist); - } - - void raw_log(Verbosity verbosity, const char* file, unsigned line, const char* format, ...) - { - va_list vlist; - va_start(vlist, format); - auto buff = vtextprintf(format, vlist); - auto message = Message{verbosity, file, line, "", "", "", buff.c_str()}; - log_message(1, message, false, true); - va_end(vlist); - } -#endif - - void flush() - { - std::lock_guard lock(s_mutex); - fflush(stderr); - for (const auto& callback : s_callbacks) - { - if (callback.flush) { - callback.flush(callback.user_data); - } - } - s_needs_flushing = false; - } - - LogScopeRAII::LogScopeRAII(Verbosity verbosity, const char* file, unsigned line, const char* format, ...) - : _verbosity(verbosity), _file(file), _line(line) - { - if (verbosity <= current_verbosity_cutoff()) { - std::lock_guard lock(s_mutex); - _indent_stderr = (verbosity <= g_stderr_verbosity); - _start_time_ns = now_ns(); - va_list vlist; - va_start(vlist, format); - vsnprintf(_name, sizeof(_name), format, vlist); - log_to_everywhere(1, _verbosity, file, line, "{ ", _name); - va_end(vlist); - - if (_indent_stderr) { - ++s_stderr_indentation; - } - - for (auto& p : s_callbacks) { - if (verbosity <= p.verbosity) { - ++p.indentation; - } - } - } else { - _file = nullptr; - } - } - - LogScopeRAII::~LogScopeRAII() - { - if (_file) { - std::lock_guard lock(s_mutex); - if (_indent_stderr && s_stderr_indentation > 0) { - --s_stderr_indentation; - } - for (auto& p : s_callbacks) { - // Note: Callback indentation cannot change! - if (_verbosity <= p.verbosity) { - // in unlikely case this callback is new - if (p.indentation > 0) { - --p.indentation; - } - } - } -#if LOGURU_VERBOSE_SCOPE_ENDINGS - auto duration_sec = (now_ns() - _start_time_ns) / 1e9; - auto buff = textprintf("%.*f s: %s", LOGURU_SCOPE_TIME_PRECISION, duration_sec, _name); - log_to_everywhere(1, _verbosity, _file, _line, "} ", buff.c_str()); -#else - log_to_everywhere(1, _verbosity, _file, _line, "}", ""); -#endif - } - } - - void log_and_abort(int stack_trace_skip, const char* expr, const char* file, unsigned line, const char* format, ...) - { - va_list vlist; - va_start(vlist, format); - auto buff = vtextprintf(format, vlist); - log_to_everywhere(stack_trace_skip + 1, Verbosity_FATAL, file, line, expr, buff.c_str()); - va_end(vlist); - abort(); // log_to_everywhere already does this, but this makes the analyzer happy. - } - - void log_and_abort(int stack_trace_skip, const char* expr, const char* file, unsigned line) - { - log_and_abort(stack_trace_skip + 1, expr, file, line, " "); - } - - // ---------------------------------------------------------------------------- - // Streams: - - std::string vstrprintf(const char* format, va_list vlist) - { - auto text = vtextprintf(format, vlist); - std::string result = text.c_str(); - return result; - } - - std::string strprintf(const char* format, ...) - { - va_list vlist; - va_start(vlist, format); - auto result = vstrprintf(format, vlist); - va_end(vlist); - return result; - } - - #if LOGURU_WITH_STREAMS - - StreamLogger::~StreamLogger() noexcept(false) - { - auto message = _ss.str(); - log(_verbosity, _file, _line, "%s", message.c_str()); - } - - AbortLogger::~AbortLogger() noexcept(false) - { - auto message = _ss.str(); - loguru::log_and_abort(1, _expr, _file, _line, "%s", message.c_str()); - } - - #endif // LOGURU_WITH_STREAMS - - // ---------------------------------------------------------------------------- - // 888888 88""Yb 88""Yb dP"Yb 88""Yb dP""b8 dP"Yb 88b 88 888888 888888 Yb dP 888888 - // 88__ 88__dP 88__dP dP Yb 88__dP dP `" dP Yb 88Yb88 88 88__ YbdP 88 - // 88"" 88"Yb 88"Yb Yb dP 88"Yb Yb Yb dP 88 Y88 88 88"" dPYb 88 - // 888888 88 Yb 88 Yb YbodP 88 Yb YboodP YbodP 88 Y8 88 888888 dP Yb 88 - // ---------------------------------------------------------------------------- - - struct StringStream - { - std::string str; - }; - - // Use this in your EcPrinter implementations. - void stream_print(StringStream& out_string_stream, const char* text) - { - out_string_stream.str += text; - } - - // ---------------------------------------------------------------------------- - - using ECPtr = EcEntryBase*; - -#if defined(_WIN32) || (defined(__APPLE__) && !TARGET_OS_IPHONE) - #ifdef __APPLE__ - #define LOGURU_THREAD_LOCAL __thread - #else - #define LOGURU_THREAD_LOCAL thread_local - #endif - static LOGURU_THREAD_LOCAL ECPtr thread_ec_ptr = nullptr; - - ECPtr& get_thread_ec_head_ref() - { - return thread_ec_ptr; - } -#else // !thread_local - static pthread_once_t s_ec_pthread_once = PTHREAD_ONCE_INIT; - static pthread_key_t s_ec_pthread_key; - - void free_ec_head_ref(void* io_error_context) - { - delete reinterpret_cast(io_error_context); - } - - void ec_make_pthread_key() - { - (void)pthread_key_create(&s_ec_pthread_key, free_ec_head_ref); - } - - ECPtr& get_thread_ec_head_ref() - { - (void)pthread_once(&s_ec_pthread_once, ec_make_pthread_key); - auto ec = reinterpret_cast(pthread_getspecific(s_ec_pthread_key)); - if (ec == nullptr) { - ec = new ECPtr(nullptr); - (void)pthread_setspecific(s_ec_pthread_key, ec); - } - return *ec; - } -#endif // !thread_local - - // ---------------------------------------------------------------------------- - - EcHandle get_thread_ec_handle() - { - return get_thread_ec_head_ref(); - } - - Text get_error_context() - { - return get_error_context_for(get_thread_ec_head_ref()); - } - - Text get_error_context_for(const EcEntryBase* ec_head) - { - std::vector stack; - while (ec_head) { - stack.push_back(ec_head); - ec_head = ec_head->_previous; - } - std::reverse(stack.begin(), stack.end()); - - StringStream result; - if (!stack.empty()) { - result.str += "------------------------------------------------\n"; - for (auto entry : stack) { - const auto description = std::string(entry->_descr) + ":"; - auto prefix = textprintf("[ErrorContext] %*s:%-5u %-20s ", - LOGURU_FILENAME_WIDTH, filename(entry->_file), entry->_line, description.c_str()); - result.str += prefix.c_str(); - entry->print_value(result); - result.str += "\n"; - } - result.str += "------------------------------------------------"; - } - return Text(STRDUP(result.str.c_str())); - } - - EcEntryBase::EcEntryBase(const char* file, unsigned line, const char* descr) - : _file(file), _line(line), _descr(descr) - { - EcEntryBase*& ec_head = get_thread_ec_head_ref(); - _previous = ec_head; - ec_head = this; - } - - EcEntryBase::~EcEntryBase() - { - get_thread_ec_head_ref() = _previous; - } - - // ------------------------------------------------------------------------ - - Text ec_to_text(const char* value) - { - // Add quotes around the string to make it obvious where it begin and ends. - // This is great for detecting erroneous leading or trailing spaces in e.g. an identifier. - auto str = "\"" + std::string(value) + "\""; - return Text{STRDUP(str.c_str())}; - } - - Text ec_to_text(char c) - { - // Add quotes around the character to make it obvious where it begin and ends. - std::string str = "'"; - - auto write_hex_digit = [&](unsigned num) - { - if (num < 10u) { str += char('0' + num); } - else { str += char('a' + num - 10); } - }; - - auto write_hex_16 = [&](uint16_t n) - { - write_hex_digit((n >> 12u) & 0x0f); - write_hex_digit((n >> 8u) & 0x0f); - write_hex_digit((n >> 4u) & 0x0f); - write_hex_digit((n >> 0u) & 0x0f); - }; - - if (c == '\\') { str += "\\\\"; } - else if (c == '\"') { str += "\\\""; } - else if (c == '\'') { str += "\\\'"; } - else if (c == '\0') { str += "\\0"; } - else if (c == '\b') { str += "\\b"; } - else if (c == '\f') { str += "\\f"; } - else if (c == '\n') { str += "\\n"; } - else if (c == '\r') { str += "\\r"; } - else if (c == '\t') { str += "\\t"; } - else if (0 <= c && c < 0x20) { - str += "\\u"; - write_hex_16(static_cast(c)); - } else { str += c; } - - str += "'"; - - return Text{STRDUP(str.c_str())}; - } - - #define DEFINE_EC(Type) \ - Text ec_to_text(Type value) \ - { \ - auto str = std::to_string(value); \ - return Text{STRDUP(str.c_str())}; \ - } - - DEFINE_EC(int) - DEFINE_EC(unsigned int) - DEFINE_EC(long) - DEFINE_EC(unsigned long) - DEFINE_EC(long long) - DEFINE_EC(unsigned long long) - DEFINE_EC(float) - DEFINE_EC(double) - DEFINE_EC(long double) - - #undef DEFINE_EC - - Text ec_to_text(EcHandle ec_handle) - { - Text parent_ec = get_error_context_for(ec_handle); - char* with_newline = reinterpret_cast(malloc(strlen(parent_ec.c_str()) + 2)); - with_newline[0] = '\n'; - strcpy(with_newline + 1, parent_ec.c_str()); - return Text(with_newline); - } - - // ---------------------------------------------------------------------------- - -} // namespace loguru - -// ---------------------------------------------------------------------------- -// .dP"Y8 88 dP""b8 88b 88 db 88 .dP"Y8 -// `Ybo." 88 dP `" 88Yb88 dPYb 88 `Ybo." -// o.`Y8b 88 Yb "88 88 Y88 dP__Yb 88 .o o.`Y8b -// 8bodP' 88 YboodP 88 Y8 dP""""Yb 88ood8 8bodP' -// ---------------------------------------------------------------------------- - -#ifdef _WIN32 -namespace loguru { - void install_signal_handlers() - { - #if defined(_MSC_VER) - #pragma message ( "No signal handlers on Win32" ) - #else - #warning "No signal handlers on Win32" - #endif - } -} // namespace loguru - -#else // _WIN32 - -namespace loguru -{ - struct Signal - { - int number; - const char* name; - }; - const Signal ALL_SIGNALS[] = { -#if LOGURU_CATCH_SIGABRT - { SIGABRT, "SIGABRT" }, -#endif - { SIGBUS, "SIGBUS" }, - { SIGFPE, "SIGFPE" }, - { SIGILL, "SIGILL" }, - { SIGINT, "SIGINT" }, - { SIGSEGV, "SIGSEGV" }, - { SIGTERM, "SIGTERM" }, - }; - - void write_to_stderr(const char* data, size_t size) - { - auto result = write(STDERR_FILENO, data, size); - (void)result; // Ignore errors. - } - - void write_to_stderr(const char* data) - { - write_to_stderr(data, strlen(data)); - } - - void call_default_signal_handler(int signal_number) - { - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sig_action.sa_handler = SIG_DFL; - sigaction(signal_number, &sig_action, NULL); - kill(getpid(), signal_number); - } - - void signal_handler(int signal_number, siginfo_t*, void*) - { - const char* signal_name = "UNKNOWN SIGNAL"; - - for (const auto& s : ALL_SIGNALS) { - if (s.number == signal_number) { - signal_name = s.name; - break; - } - } - - // -------------------------------------------------------------------- - /* There are few things that are safe to do in a signal handler, - but writing to stderr is one of them. - So we first print out what happened to stderr so we're sure that gets out, - then we do the unsafe things, like logging the stack trace. - */ - - if (g_colorlogtostderr && s_terminal_has_color) { - write_to_stderr(terminal_reset()); - write_to_stderr(terminal_bold()); - write_to_stderr(terminal_light_red()); - } - write_to_stderr("\n"); - write_to_stderr("Loguru caught a signal: "); - write_to_stderr(signal_name); - write_to_stderr("\n"); - if (g_colorlogtostderr && s_terminal_has_color) { - write_to_stderr(terminal_reset()); - } - - // -------------------------------------------------------------------- - -#if LOGURU_UNSAFE_SIGNAL_HANDLER - // -------------------------------------------------------------------- - /* Now we do unsafe things. This can for example lead to deadlocks if - the signal was triggered from the system's memory management functions - and the code below tries to do allocations. - */ - - flush(); - char preamble_buff[LOGURU_PREAMBLE_WIDTH]; - print_preamble(preamble_buff, sizeof(preamble_buff), Verbosity_FATAL, "", 0); - auto message = Message{Verbosity_FATAL, "", 0, preamble_buff, "", "Signal: ", signal_name}; - try { - log_message(1, message, false, false); - } catch (...) { - // This can happed due to s_fatal_handler. - write_to_stderr("Exception caught and ignored by Loguru signal handler.\n"); - } - flush(); - - // -------------------------------------------------------------------- -#endif // LOGURU_UNSAFE_SIGNAL_HANDLER - - call_default_signal_handler(signal_number); - } - - void install_signal_handlers() - { - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sig_action.sa_flags |= SA_SIGINFO; - sig_action.sa_sigaction = &signal_handler; - for (const auto& s : ALL_SIGNALS) { - CHECK_F(sigaction(s.number, &sig_action, NULL) != -1, - "Failed to install handler for %s", s.name); - } - } -} // namespace loguru - -#endif // _WIN32 - -#endif // LOGURU_IMPLEMENTATION diff --git a/meson.build b/meson.build index 8d6ccd1..68d7bd9 100644 --- a/meson.build +++ b/meson.build @@ -22,7 +22,6 @@ endif root_inc = include_directories('./') subdir('protocol') -subdir('libloguru') subdir('libaurum') if get_option('tizen') == true subdir('org.tizen.aurum-bootstrap') diff --git a/org.tizen.aurum-bootstrap/meson.build b/org.tizen.aurum-bootstrap/meson.build index eb6cfd0..d4da42d 100644 --- a/org.tizen.aurum-bootstrap/meson.build +++ b/org.tizen.aurum-bootstrap/meson.build @@ -3,7 +3,6 @@ bootstrap_svr_inc = [ root_inc, include_directories('inc'), include_directories('inc/Commands'), - loguru_inc, ] bootstrap_svr_src = [ @@ -44,7 +43,6 @@ bootstrap_svr_src += [ bootstrap_svr_dep = [ libaurum, grpc_deps, - loguru_deps, ] if get_option('tizen') == true @@ -65,7 +63,6 @@ bootstrap_svr_bin = executable( [bootstrap_svr_src, grpc_src, grpc_pb_src], dependencies: bootstrap_svr_dep, include_directories: bootstrap_svr_inc, - link_with: libloguru, install:true, install_dir: join_paths(get_option('tzapp_path'), 'org.tizen.aurum-bootstrap', 'bin'), pie:true, diff --git a/tests/Test_Misc.cc b/tests/Test_Misc.cc index f5f4a74..d6793f7 100644 --- a/tests/Test_Misc.cc +++ b/tests/Test_Misc.cc @@ -10,9 +10,6 @@ #include #include -#include - - #include "MockAccessibleWatcher.h" #include "MockAccessibleApplication.h" #include "MockAccessibleWindow.h" diff --git a/tests/Test_Sel.cc b/tests/Test_Sel.cc index 6937683..cef1c7f 100644 --- a/tests/Test_Sel.cc +++ b/tests/Test_Sel.cc @@ -10,9 +10,6 @@ #include #include -#include - - #include "MockAccessibleWatcher.h" #include "MockAccessibleApplication.h" #include "MockAccessibleWindow.h" @@ -22,7 +19,6 @@ class AurumTestSel : public ::testing::Test { public: AurumTestSel() : mDevice{nullptr}, mWatcher{nullptr}, mApps{}, mWins{}, mNodes{}{ - //loguru::g_stderr_verbosity = loguru::Verbosity_9; } protected: void SetUp() override { diff --git a/tests/Test_UiDevice.cc b/tests/Test_UiDevice.cc index 2a054cd..b46b312 100644 --- a/tests/Test_UiDevice.cc +++ b/tests/Test_UiDevice.cc @@ -6,7 +6,6 @@ #include #include - #include "MockDeviceImpl.h" #include @@ -14,9 +13,6 @@ #include #include -#include - - #include "MockAccessibleWatcher.h" #include "MockAccessibleApplication.h" #include "MockAccessibleWindow.h" @@ -27,7 +23,6 @@ class AurumTestUiDevice : public ::testing::Test { public: AurumTestUiDevice() : mDevice{nullptr}, mWatcher{nullptr}, mApp{nullptr}, mWin{nullptr}, mNode{nullptr} { - //loguru::g_stderr_verbosity = loguru::Verbosity_9; } void SetUp() override { @@ -319,4 +314,4 @@ TEST_F(AurumTestUiDevice, getSystemTime_P1) clock_gettime(CLOCK_REALTIME, &t); long long t4 = (long long)t.tv_sec * 1000L + (long long)(t.tv_nsec / 1000000); ASSERT_NEAR(t3,t4,100); -} \ No newline at end of file +} diff --git a/tests/Test_UiObject.cc b/tests/Test_UiObject.cc index 8bd2915..a08a8f9 100644 --- a/tests/Test_UiObject.cc +++ b/tests/Test_UiObject.cc @@ -11,7 +11,6 @@ #include #include -#include #include #include @@ -24,7 +23,6 @@ class AurumTestUiObject : public ::testing::Test { public: AurumTestUiObject() : mDevice{nullptr},mWatcher{nullptr}, mApp{nullptr}, mWin{nullptr}, mNode{nullptr} { - //loguru::g_stderr_verbosity = loguru::Verbosity_9; } void SetUp() override { @@ -433,4 +431,4 @@ TEST_F(AurumTestUiObject, DoAtspiActivate_P1) TEST_F(AurumTestUiObject, refresh_P1) { -} \ No newline at end of file +} diff --git a/tests/Test_UiSelector.cc b/tests/Test_UiSelector.cc index c712d91..9f76683 100644 --- a/tests/Test_UiSelector.cc +++ b/tests/Test_UiSelector.cc @@ -10,7 +10,6 @@ #include #include -#include #include "MockAccessibleWatcher.h" @@ -22,7 +21,6 @@ class AurumTestUiSelector : public ::testing::Test { public: AurumTestUiSelector(): mDevice{nullptr}, mWatcher{nullptr}, mApps{}, mWins{}, mNodes{}{ - //loguru::g_stderr_verbosity = loguru::Verbosity_9; } protected: void SetUp() override { -- 2.34.1