// License: Modified MIT (NON-AI) // See the LICENSE file in the root directory for license information. // Copyright 2025 Timothy Prepscius #pragma once #include "../header_only/compile.h" #include "../debug/Debug.h" #include "Detail.hpp" #include "Color.hpp" #include "../io/memstream.hpp" #include "../string/as_string_view.hpp" typedef void (*TimPrepsciusCoreLogExternalPrintPtr)(const std::string_view &); void setExternalDebugPrint(TimPrepsciusCoreLogExternalPrintPtr f); void setExternalLogPrint(TimPrepsciusCoreLogExternalPrintPtr f); void setExternalConsolePrint(TimPrepsciusCoreLogExternalPrintPtr f); namespace tjp::core::log { using detail::Settings; using detail::Story; using detail::getManager; #define xLogManager() tjp::core::log::getManager() void Initialize(const std::string &fileName = {}); void Initialize(const Settings &); #define xLogInitialize(...) tjp::core::log::Initialize(__VA_ARGS__) /** * the functions actually write strings */ void WriteToLog (const std::string &); void WriteToDebugger (const std::string &); void WriteToConsole (const std::string &); /** * functions to turn on/off logs and query their state */ void ActivateStory (const Story &s); void RotateTo (const std::string_view &rotateTo); void Rotate (); void Start(); void Stop (); void ActivateStories (const std::string &fileName); //----------------------------------------------------------------------------- #if defined(_DEBUG) || defined(DEBUG) #ifndef LOG_DEBUG #define LOG_DEBUG #endif #else #ifndef LOG_DEBUG // #define LOG_DEBUG #endif #endif #define LOG_RELEASE #define LOG_ERROR #ifdef TESTING #define LOG_TEST #endif #if defined(LOG_DEBUG) || defined(LOG_RELEASE) #define xLogActivateStories(s) tjp::core::log::ActivateStories(s) #define xLogActivateStory(s) \ tjp::core::log::ActivateStory(s); \ sLogRelease(s, "logging activated") #define xLogStart() tjp::core::log::Start() #define xLogStop() tjp::core::log::Stop() #else #define xLogActivateStories(s) #define xLogActivateStory(x) #define xLogStoryActivated(x) #define xLogStart(x) #define xLogStop(x) #endif //----------------------------------------------------------------------------- #define xLogDebugStreamName "Debug" #define xLogReleaseStreamName "Release" #define xLogErrorStreamName "Error" #define xLogSettings tjp::core::log::Settings::global // ------------------------------------ #define xLogMethodName(x) tjp::core::log::detail::methodName(x) // ------------------------------------ #define xLogNoStory "_" #define xLogAllStories "*" // ------------------------------------ #ifdef LOG_DEBUG #define xFormatDebugger(p,n,story,...) __FILE__ << "(" << __LINE__ << ") : " << xLogColorStory(story) << n << " " << __VA_ARGS__ << std::endl #else #define xFormatDebugger(p,n,story,...) story << n << " " << __VA_ARGS__ << std::endl #endif #define xFormatLog(p,n,story,...) "[" << story << "] " << n << " " << __VA_ARGS__ << std::endl #define xFormatConsole(p,n,story,...) xLogColorStory(story) << n << " " << __VA_ARGS__ << std::endl #define xLogTo(useColor, where, ...) \ { \ ::tjp::core::io::omemstream_ _out; \ if (useColor) \ _out.iword(::tjp::core::log::detail::SupportsColorFlag::id()) = 1; \ _out << __VA_ARGS__; \ where(::tjp::core::as_string_view(_out.data)); \ } #define _xLog__(manager, n_,condition,story,...) \ { \ if (condition) \ { \ auto n = xLogMethodName(n_); \ if (manager.settings.LogToDebuggerActivated) \ xLogTo(false, manager.writeToDebugger, xFormatDebugger(xLogDebugStreamName,n,story,__VA_ARGS__)) \ if (manager.settings.LogToFileActivated) \ xLogTo(false, manager.writeToLog, xFormatLog(xLogDebugStreamName,n,story,__VA_ARGS__)); \ if (manager.settings.LogToConsoleActivated) \ xLogTo(manager.termSupportsColor, manager.writeToConsole, xFormatConsole(xLogDebugStreamName,n,story,__VA_ARGS__)); \ } \ } #define _xLog_(n_,condition,story,...) \ { \ auto &manager = xLogManager(); \ _xLog__(manager, n_,condition,story, __VA_ARGS__); \ } \ #define _xLog(n_,condition,story,...) \ { \ auto &manager = xLogManager(); \ if (manager.stories.isActivated(story)) \ _xLog__(manager, n_,condition,story, __VA_ARGS__); \ } \ // -------------------------------------- #define _xLogDebug(condition,story,...) _xLog(__PRETTY_FUNCTION__,condition,story,__VA_ARGS__) #define _xLogTest(condition,story,...) _xLog(__PRETTY_FUNCTION__,condition,story,__VA_ARGS__) #ifdef _DEBUG #define LOG_USE_FUNCTION_NAMES #else // #define LOG_USE_FUNCTION_NAMES #endif #ifdef LOG_USE_FUNCTION_NAMES #define _xLogRelease(condition,story,...) _xLog(__PRETTY_FUNCTION__,condition,story,__VA_ARGS__) #define _xLogError(condition,story,...) _xLog_(__PRETTY_FUNCTION__,condition,story,__VA_ARGS__) #else #define _xLogRelease(condition,story,...) _xLog(nullptr,condition,story,__VA_ARGS__) #define _xLogError(condition,story,...) _xLog_(nullptr,condition,story,__VA_ARGS__) #endif // -------------------------------------- #ifdef LOG_DEBUG #define xLogDebug(...) _xLogDebug(true,xLogNoStory,__VA_ARGS__) #define xLogDebugIf(condition,...) _xLogDebug(condition,xLogNoStory,__VA_ARGS__) #define sLogDebug(story,...) _xLogDebug(true,story,__VA_ARGS__) #define sLogDebugIf(condition,story,...) _xLogDebug(condition,story,__VA_ARGS__) #define fLogDebug(x) xLogDebug(x) #define LOG_DEBUG_ONLY(...) __VA_ARGS__ #else #define xLogDebug(...) #define xLogDebugIf(...) #define sLogDebug(...) #define sLogDebugIf(...) #define fLogDebug(...) #define LOG_DEBUG_ONLY(...) #endif #ifdef LOG_RELEASE #define xLogRelease(...) _xLogRelease(true,xLogNoStory,__VA_ARGS__) #define xLogReleaseIf(condition,...) _xLogRelease(condition,xLogNoStory,__VA_ARGS__) #define sLogRelease(story,...) _xLogRelease(true,story,__VA_ARGS__) #define sLogReleaseIf(condition,story,...) _xLogRelease(condition,story,__VA_ARGS__) #else #define xLogRelease(...) #define xLogReleaseIf(...) #define sLogRelease(...) #define sLogReleaseIf(...) #endif #ifdef LOG_TEST #define xLogTest(x) _xLogTest(true,xLogNoStory,x) #define xLogTestIf(condition,x) _xLogTest(condition,xLogNoStory,x) #define sLogTest(story,x) _xLogTest(true,story,x) #define sLogTestIf(condition,story,x) _xLogTest(condition,story,x) #else #define xLogTest(...) #define xLogTestIf(...) #define sLogTest(...) #define sLogTestIf(...) #endif #ifdef LOG_ERROR #define xLogError(...) _xLogError(true,xLogNoStory,__VA_ARGS__) #define sLogError(story,...) _xLogError(true,story,__VA_ARGS__) #define sLogErrorIf(condition,story,...) _xLogError(condition,story,__VA_ARGS__) #else #define xLogError(...) #define sLogError(...) #define sLogErrorIf(...) #endif // -------------------------------------- #define nLogDebug(...) #define nLogRelease(...) #define nLogError(...) } // namespace #ifdef TJP_CORE_HEADER_ONLY_COMPILE #include "Detail.cpp" #include "Color.cpp" #include "Log.cpp" #endif