#include "utils.h" #include #include #include #include #include #include LogLevel log_level = LOG_LEVEL_WARNING; void set_log_level(LogLevel level) { log_level = level; } void log_message(LogLevel level, const char* format, ...) { if (level < log_level) return; va_list args; va_start(args, format); const char* color; const char* level_str; // Set the color and level_str based on the log level switch (level) { case LOG_LEVEL_DEBUG: color = "\033[0;90m"; level_str = "DEBUG"; break; case LOG_LEVEL_WARNING: color = "\033[0;33m"; level_str = "WARNING"; break; case LOG_LEVEL_ERROR: color = "\033[0;31m"; level_str = "ERROR"; break; } // Get the current time time_t t = time(NULL); struct tm* tm_info = localtime(&t); // Print the label, message and newline fprintf(stderr, "%s[%02d/%02d/%02d %02d:%02d:%02d - %s]\033[m ", color, tm_info->tm_mday, tm_info->tm_mon + 1, (tm_info->tm_year + 1900) % 100, tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec, level_str); vfprintf(stderr, format, args); fprintf(stderr, "\n"); // Flush the output fflush(stderr); va_end(args); } Result format(char** out_string, const char* fmt, ...) { *out_string = NULL; va_list args; va_start(args, fmt); // Calculate the length of the formatted string size_t length = vsnprintf(NULL, 0, fmt, args) + 1; va_end(args); if (length <= 0) { log_message(LOG_LEVEL_ERROR, "Failed to calculate the length of the formatted string (%s).", strerror(errno)); return FAILURE; } // Allocate a buffer for the formatted string char* buffer = calloc(length, sizeof(char)); if (buffer == NULL) { log_message(LOG_LEVEL_ERROR, "Failed to allocate memory for the formatted string (%s).", strerror(errno)); return OUT_OF_MEMORY; } va_start(args, fmt); // Format the string vsnprintf(buffer, length, fmt, args); va_end(args); *out_string = buffer; return SUCCESS; }