#include "io/print.hpp" #include #include using namespace log; #define C_RS "\x1b[0m" #define C_BLACK "\x1b[30m" #define C_RED "\x1b[31m" #define C_GREEN "\x1b[32m" #define C_YELLOW "\x1b[33m" #define C_BLUE "\x1b[34m" #define C_MAGENTA "\x1b[35m" #define C_CYAN "\x1b[36m" #define C_WHITE "\x1b[37m" #define C_BOLD "\x1b[1m" #define C_DIM "\x1b[2m" #define C_ITALIC "\x1b[3m" #define C_UL "\x1b[4m" #define C_BLINK "\x1b[5m" extern "C" char* getenv(const char* name); Logger::Logger() { char* val = getenv("CPLUS_LOG"); if (val != NULL) { if (strcmp(val, "OFF") == 0) { this->set_log_level(LOG_OFF); } else if (strcmp(val, "ERROR") == 0) { this->set_log_level(LOG_ERROR); } else if (strcmp(val, "WARN") == 0) { this->set_log_level(LOG_WARN); } else if (strcmp(val, "INFO") == 0) { this->set_log_level(LOG_INFO); } else if (strcmp(val, "DEBUG") == 0) { this->set_log_level(LOG_DEBUG); } } val = getenv("CPLUS_LOG_COLOR"); // clang-format off if (val != NULL) { if ( strcmp(val, "false") == 0 || strcmp(val, "FALSE") == 0 || strcmp(val, "off") == 0 || strcmp(val, "OFF") == 0 || strcmp(val, "no") == 0 || strcmp(val, "NO") == 0 ) { this->load_default_prefixes(); } else { this->load_default_prefixes_with_color(); } } else { this->load_default_prefixes_with_color(); } } void Logger::log(LogLevel level, const char* file, const int line, const char* func, const char* str) { String s = String(str); Logger::log(level, file, line, func, s); } void Logger::log(LogLevel level, const char* file, const int line, const char* func, String str) { if (!this->should_display(level)) { return; } println(this->get_prefix(level), file, line, func, str); } void Logger::set_log_level(LogLevel level) { this->filter_level = level; } // Fucking c++ and its implicit member variable access, god forbid C++ code looks clean. const char* Logger::get_prefix(LogLevel level) { return this->prefixes[level]; } void Logger::load_default_prefixes_with_color() { // clang-format off this->prefixes[LOG_ERROR] = C_UL "{}" C_RS ":" C_UL "{}" C_RS ":" C_CYAN " [" C_RS C_RED "ERROR" C_RS C_CYAN "] (" C_RS "{}" C_CYAN ")" C_RS ": {}"; this->prefixes[LOG_WARN] = C_UL "{}" C_RS ":" C_UL "{}" C_RS ":" C_CYAN " [" C_RS C_YELLOW "WARN" C_RS C_CYAN "] (" C_RS "{}" C_CYAN ")" C_RS ": {}"; this->prefixes[LOG_INFO] = C_UL "{}" C_RS ":" C_UL "{}" C_RS ":" C_CYAN " [" C_RS C_GREEN "INFO" C_RS C_CYAN "] (" C_RS "{}" C_CYAN ")" C_RS ": {}"; this->prefixes[LOG_DEBUG] = C_UL "{}" C_RS ":" C_UL "{}" C_RS ":" C_CYAN " [" C_RS C_MAGENTA "DEBUG" C_RS C_CYAN "] (" C_RS "{}" C_CYAN ")" C_RS ": {}"; // clang-format on } void Logger::load_default_prefixes() { this->prefixes[LOG_ERROR] = "{}:{}: [ERROR] ({}): {}"; this->prefixes[LOG_WARN] = "{}:{}: [WARN] ({}): {}"; this->prefixes[LOG_INFO] = "{}:{}: [INFO] ({}): {}"; this->prefixes[LOG_DEBUG] = "{}:{}: [DEBUG] ({}): {}"; } void Logger::load_custom_prefixes(const char* pfx[LOG_LEVEL_COUNT]) { for (int i = 0; i < LOG_LEVEL_COUNT; i++) { this->prefixes[i] = pfx[i]; } } bool Logger::should_display(LogLevel level) { return this->filter_level >= level; }