#ifndef CORE_LOGGER_H #define CORE_LOGGER_H #include "utils/ArrayString.h" namespace Core::Logger { enum class Level { ERROR, WARNING, INFO, DEBUG }; extern Level level; // 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 = Core::getFileName(file); Core::ArrayString<2048> s; if(s.append(start) || s.append("#:# | ") || s.format(file, line)) { CORE_EXIT(1); } else if(s.append(format)) { CORE_EXIT(1); } else if(s.format(Core::forward(args)...)) { CORE_EXIT(1); } else if(s.append("\33[39;49m\n") || 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