#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; 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* start, const char* format, Args&&... args) { if(Core::Logger::level < l) { return; } file = getFileName(file); Core::String32<2048> s; if(filterError(s.append(start)) || filterError(s.append("#:# | ")) || filterError(s.format(file, line)) || filterError(s.append(format)) || filterError(s.format(Core::forward(args)...)) || filterError(s.append("\33[0m\n")) || filterError(s.print())) { CORE_EXIT(1); } } } #if defined(CORE_LOG_LEVEL) && CORE_LOG_LEVEL >= 1 #define CORE_LOG_ERROR(format, ...) \ log(Core::Logger::Level::ERROR, __FILE__, __LINE__, "\33[1;31m[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__, \ "\33[1;33m[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__, "\33[1;37m[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__, "\33[1;32m[DEBUG] ", \ format __VA_OPT__(, ) __VA_ARGS__); #else #define CORE_LOG_DEBUG(format, ...) #endif #endif