#ifndef CORE_LOGGER_HPP #define CORE_LOGGER_HPP #include "core/utils/ArrayString.hpp" namespace Core::Logger { enum class Level { ERROR, WARNING, INFO, DEBUG }; extern Level level; [[maybe_unused]] static constexpr const char* COLOR_RED = "\33[1;31m"; [[maybe_unused]] static constexpr const char* COLOR_YELLOW = "\33[1;33m"; [[maybe_unused]] static constexpr const char* COLOR_GRAY = "\33[1;37m"; [[maybe_unused]] static constexpr const char* COLOR_GREEN = "\33[1;32m"; [[maybe_unused]] static constexpr const char* COLOR_RESET = "\33[0m"; const char* getFileName(const char* path); inline bool filterError(Error e) { return e != Error::NONE && e != Error::CAPACITY_REACHED; } // aborts on critical logging failure template void log(Level l, const char* file, int line, const char* prefix, const char* tag, const char* format, Args&&... args) { if(Core::Logger::level < l) { return; } file = getFileName(file); Core::String32<2048> s; if(filterError(s.append(prefix)) || filterError(s.append(tag)) || filterError(s.append("#:# | ")) || filterError(s.format(file, line)) || filterError(s.append(format)) || filterError(s.format(Core::forward(args)...)) || filterError(s.append(COLOR_RESET)) || filterError(s.printLine())) { CORE_EXIT(1); // CoverageIgnore } } template void log(const char* prefix, const char* format, Args&&... args) { Core::String32<2048> s; if(filterError(s.append(prefix)) || filterError(s.append(format)) || filterError(s.format(Core::forward(args)...)) || filterError(s.append(COLOR_RESET)) || filterError(s.printLine())) { CORE_EXIT(1); // CoverageIgnore } } } #if defined(CORE_LOG_LEVEL) && CORE_LOG_LEVEL >= 1 #define CORE_LOG_ERROR(format, ...) \ log(Core::Logger::Level::ERROR, __FILE__, __LINE__, \ Core::Logger::COLOR_RED, "[ERROR] ", \ format __VA_OPT__(, ) __VA_ARGS__); #else #define CORE_LOG_ERROR(format, ...) #endif #if defined(CORE_LOG_LEVEL) && CORE_LOG_LEVEL >= 2 #define CORE_LOG_WARNING(format, ...) \ log(Core::Logger::Level::WARNING, __FILE__, __LINE__, \ Core::Logger::COLOR_YELLOW, "[WARNING] ", \ format __VA_OPT__(, ) __VA_ARGS__); #else #define CORE_LOG_WARNING(format, ...) #endif #if defined(CORE_LOG_LEVEL) && CORE_LOG_LEVEL >= 3 #define CORE_LOG_INFO(format, ...) \ log(Core::Logger::Level::INFO, __FILE__, __LINE__, \ Core::Logger::COLOR_GRAY, "[INFO] ", \ format __VA_OPT__(, ) __VA_ARGS__); #else #define CORE_LOG_INFO(format, ...) #endif #if defined(CORE_LOG_LEVEL) && CORE_LOG_LEVEL >= 4 #define CORE_LOG_DEBUG(format, ...) \ log(Core::Logger::Level::DEBUG, __FILE__, __LINE__, \ Core::Logger::COLOR_GREEN, "[DEBUG] ", \ format __VA_OPT__(, ) __VA_ARGS__); #else #define CORE_LOG_DEBUG(format, ...) #endif #endif