orca/src/util/debug_log.c

125 lines
2.5 KiB
C

/************************************************************//**
*
* @file: debug_log.c
* @author: Martin Fouilleul
* @date: 22/10/2020
* @revision:
*
*****************************************************************/
#include<stdarg.h>
#include<string.h>
#include"debug_log.h"
static const char* LOG_HEADINGS[LOG_LEVEL_COUNT] = {
"Error",
"Warning",
"Message",
"Debug"};
static const char* LOG_FORMATS[LOG_LEVEL_COUNT] = {
"\033[38;5;9m\033[1m",
"\033[38;5;13m\033[1m",
"\033[38;5;10m\033[1m",
"\033[38;5;14m\033[1m" };
static const char* LOG_FORMAT_STOP = "\033[m";
enum {
LOG_SUBSYSTEM_MAX_COUNT = 16 };
typedef struct log_config
{
FILE* out;
log_level level;
const char* subsystemNames[LOG_SUBSYSTEM_MAX_COUNT];
log_level subsystemLevels[LOG_SUBSYSTEM_MAX_COUNT];
} log_config;
static log_config __log_config = {.out = 0,
.level = LOG_DEFAULT_LEVEL,
.subsystemNames = {0},
.subsystemLevels = {0}};
int LogFindSubsystem(const char* subsystem)
{
for(int i=0; i<LOG_SUBSYSTEM_MAX_COUNT; i++)
{
if(__log_config.subsystemNames[i])
{
if(!strcmp(__log_config.subsystemNames[i], subsystem))
{
return(i);
}
}
}
return(-1);
}
void LogGeneric(log_level level,
const char* subsystem,
const char* functionName,
const char* fileName,
u32 line,
const char* msg,
...)
{
int subsystemIndex = LogFindSubsystem(subsystem);
int filterLevel = (subsystemIndex >= 0)? __log_config.subsystemLevels[subsystemIndex] : __log_config.level;
if(level <= filterLevel)
{
if(!__log_config.out)
{
__log_config.out = LOG_DEFAULT_OUTPUT;
}
fprintf(__log_config.out,
"%s%s:%s [%s] %s() in %s:%i: ",
LOG_FORMATS[level],
LOG_HEADINGS[level],
LOG_FORMAT_STOP,
subsystem,
functionName,
fileName,
line);
va_list ap;
va_start(ap, msg);
vfprintf(__log_config.out, msg, ap);
va_end(ap);
}
}
void LogOutput(FILE* output)
{
__log_config.out = output;
}
void LogLevel(log_level level)
{
__log_config.level = level;
}
void LogFilter(const char* subsystem, log_level level)
{
int firstNull = -1;
for(int i=0; i<LOG_SUBSYSTEM_MAX_COUNT; i++)
{
if(__log_config.subsystemNames[i])
{
if(!strcmp(__log_config.subsystemNames[i], subsystem))
{
__log_config.subsystemLevels[i] = level;
return;
}
}
else if(firstNull < 0)
{
firstNull = i;
}
}
__log_config.subsystemNames[firstNull] = subsystem;
__log_config.subsystemLevels[firstNull] = level;
}