module; #include #include export module Core.Logger; import Core.Terminal; import Core.Meta; import Core.ToString; #define SOURCE const std::source_location& sl = std::source_location::current() export namespace Core { enum class LogLevel { NONE, ERROR, WARNING, INFO, DEBUG }; extern LogLevel logLevel; using ReportHandler = void (*)( LogLevel l, const std::source_location& sl, void* data, const char* message); void callReportHandler(LogLevel l, const char* report, SOURCE); void setReportHandler(ReportHandler h, void* data); struct FormatLocation final { const char* format; std::source_location location; FormatLocation( const char* f, const std::source_location& l = std::source_location::current()) : format(f), location(l) { } }; template void report(LogLevel l, const FormatLocation& format, Args&&... args) { char buffer[512]; formatBuffer( buffer, sizeof(buffer), format.format, Core::forward(args)...); callReportHandler(l, buffer, format.location); } const char* getShortFileName(const char* s); template void log( LogLevel l, const char* prefix, const FormatLocation& format, Args&&... args) { if(logLevel < l) { return; } const char* file = getShortFileName(format.location.file_name()); fputs(prefix, stdout); printf("%s:%u | ", file, format.location.line()); char buffer[512]; formatBuffer( buffer, sizeof(buffer), format.format, Core::forward(args)...); fputs(buffer, stdout); puts(Terminal::RESET); } template void logError(const FormatLocation& format, Args&&... args) { if constexpr(LOG_LEVEL >= 1) { char buffer[32]; snprintf(buffer, sizeof(buffer), "%s[ERROR] ", Terminal::FG_RED); log(LogLevel::ERROR, buffer, format, forward(args)...); } } template void logWarning(const FormatLocation& format, Args&&... args) { if constexpr(LOG_LEVEL >= 2) { char buffer[32]; snprintf( buffer, sizeof(buffer), "%s[WARNING] ", Terminal::FG_BRIGHT_YELLOW); log(LogLevel::WARNING, buffer, format, forward(args)...); } } template void logInfo(const FormatLocation& format, Args&&... args) { if constexpr(LOG_LEVEL >= 3) { char buffer[32]; snprintf(buffer, sizeof(buffer), "%s[INFO] ", Terminal::BOLD); log(LogLevel::INFO, buffer, format, forward(args)...); } } template void logDebug(const FormatLocation& format, Args&&... args) { if constexpr(LOG_LEVEL >= 4) { char buffer[32]; snprintf( buffer, sizeof(buffer), "%s%s[DEBUG] ", Terminal::BOLD, Terminal::FG_BRIGHT_BLACK); log(LogLevel::DEBUG, buffer, format, forward(args)...); } } }