2024-02-15 19:42:22 +01:00
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <time.h>
|
2024-02-17 00:40:09 +01:00
|
|
|
#include <stdlib.h>
|
2024-02-15 19:42:22 +01:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
LogLevel log_level = LOG_LEVEL_WARNING;
|
2024-02-15 19:42:22 +01:00
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
void set_log_level(LogLevel level) {
|
|
|
|
log_level = level;
|
2024-02-15 19:42:22 +01:00
|
|
|
}
|
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
void log_message(LogLevel level, const char* format, ...) {
|
|
|
|
if (level < log_level)
|
|
|
|
return;
|
|
|
|
|
2024-02-15 19:42:22 +01:00
|
|
|
va_list args;
|
2024-02-17 00:40:09 +01:00
|
|
|
va_start(args, format);
|
2024-02-15 19:42:22 +01:00
|
|
|
|
|
|
|
const char* color;
|
|
|
|
const char* level_str;
|
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
// Set the color and level_str based on the log level
|
2024-02-15 19:42:22 +01:00
|
|
|
switch (level) {
|
2024-02-17 00:40:09 +01:00
|
|
|
case LOG_LEVEL_DEBUG:
|
2024-02-15 19:42:22 +01:00
|
|
|
color = "\033[0;90m";
|
|
|
|
level_str = "DEBUG";
|
|
|
|
break;
|
2024-02-17 00:40:09 +01:00
|
|
|
case LOG_LEVEL_WARNING:
|
2024-02-15 19:42:22 +01:00
|
|
|
color = "\033[0;33m";
|
2024-02-17 00:40:09 +01:00
|
|
|
level_str = "WARNING";
|
2024-02-15 19:42:22 +01:00
|
|
|
break;
|
2024-02-17 00:40:09 +01:00
|
|
|
case LOG_LEVEL_ERROR:
|
2024-02-15 19:42:22 +01:00
|
|
|
color = "\033[0;31m";
|
|
|
|
level_str = "ERROR";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the current time
|
|
|
|
time_t t = time(NULL);
|
|
|
|
struct tm* tm_info = localtime(&t);
|
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
// Print the label, message and newline
|
2024-02-15 19:42:22 +01:00
|
|
|
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);
|
2024-02-17 00:40:09 +01:00
|
|
|
vfprintf(stderr, format, args);
|
2024-02-15 19:42:22 +01:00
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
|
|
|
// Flush the output
|
|
|
|
fflush(stderr);
|
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
Result format(char** out_string, const char* fmt, ...) {
|
|
|
|
*out_string = NULL;
|
2024-02-15 19:42:22 +01:00
|
|
|
|
|
|
|
va_list args;
|
2024-02-17 00:40:09 +01:00
|
|
|
va_start(args, fmt);
|
2024-02-15 19:42:22 +01:00
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
// Calculate the length of the formatted string
|
|
|
|
size_t length = vsnprintf(NULL, 0, fmt, args) + 1;
|
2024-02-15 19:42:22 +01:00
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
if (length <= 0) {
|
|
|
|
log_message(LOG_LEVEL_ERROR, "Failed to calculate the length of the formatted string (%s).", strerror(errno));
|
|
|
|
return FAILURE;
|
2024-02-15 19:42:22 +01:00
|
|
|
}
|
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
// 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;
|
2024-02-15 19:42:22 +01:00
|
|
|
}
|
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
va_start(args, fmt);
|
2024-02-15 19:42:22 +01:00
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
// Format the string
|
|
|
|
vsnprintf(buffer, length, fmt, args);
|
2024-02-15 19:42:22 +01:00
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
*out_string = buffer;
|
|
|
|
return SUCCESS;
|
2024-02-15 19:42:22 +01:00
|
|
|
}
|