153 lines
4.4 KiB
C
153 lines
4.4 KiB
C
#ifndef LOG_H
|
|
#define LOG_H
|
|
|
|
#include "string.h"
|
|
|
|
#define LOG_LEVEL(l) (l <= LOG_LEVEL_COMPTIME)
|
|
|
|
/* Log level configuration */
|
|
#ifndef LOG_LEVEL_COMPTIME
|
|
# if RTC || PROFILING
|
|
# define LOG_LEVEL_COMPTIME LOG_LEVEL_DEBUG
|
|
# else
|
|
# define LOG_LEVEL_COMPTIME LOG_LEVEL_INFO
|
|
# endif
|
|
#endif
|
|
|
|
/* Source location configuration */
|
|
#ifndef LOG_INCLUDE_SOURCE_LOCATION
|
|
# define LOG_INCLUDE_SOURCE_LOCATION (DEBINFO)
|
|
#endif
|
|
|
|
#define LOG_LEVEL_NONE -1
|
|
#define LOG_LEVEL_CRITICAL 0
|
|
#define LOG_LEVEL_ERROR 1
|
|
#define LOG_LEVEL_WARNING 2
|
|
#define LOG_LEVEL_INFO 3
|
|
#define LOG_LEVEL_DEBUG 4
|
|
#define LOG_LEVEL_COUNT 5
|
|
|
|
/* ========================== *
|
|
* Callback interface
|
|
* ========================== */
|
|
|
|
struct log_level_settings {
|
|
struct string shorthand;
|
|
u32 color;
|
|
};
|
|
|
|
struct log_event {
|
|
i32 level;
|
|
struct string msg; /* Lifetime is only as long as the callback function call receiving the event */
|
|
struct log_level_settings settings;
|
|
|
|
/* These will be nulled if LOG_INCLUDE_SOURCE_LOCATION is disabled */
|
|
struct string file;
|
|
i32 line;
|
|
};
|
|
|
|
typedef void (log_event_callback_func)(struct log_event);
|
|
|
|
void log_register_callback(log_event_callback_func *func);
|
|
|
|
/* ========================== *
|
|
* Logging macros
|
|
* ========================== */
|
|
|
|
#define log_panic(msg) _log_panic(msg)
|
|
|
|
#if LOG_LEVEL(LOG_LEVEL_CRITICAL)
|
|
# if LOG_INCLUDE_SOURCE_LOCATION
|
|
# define log_critical(msg) _log(LOG_LEVEL_CRITICAL, LIT(__FILE__), __LINE__, msg)
|
|
# define logf_critical(fmt, ...) _logf(LOG_LEVEL_CRITICAL, LIT(__FILE__), __LINE__, LIT(fmt) , ## __VA_ARGS__, FMT_END)
|
|
# else
|
|
# define log_critical(msg) _log(LOG_LEVEL_CRITICAL, msg)
|
|
# define logf_critical(fmt, ...) _logf(LOG_LEVEL_CRITICAL, LIT(fmt) , ## __VA_ARGS__, FMT_END)
|
|
# endif
|
|
#else
|
|
# define log_critical(msg)
|
|
# define logf_critical(fmt, ...)
|
|
#endif
|
|
|
|
#if LOG_LEVEL(LOG_LEVEL_ERROR)
|
|
# if LOG_INCLUDE_SOURCE_LOCATION
|
|
# define log_error(msg) _log(LOG_LEVEL_ERROR, LIT(__FILE__), __LINE__, msg)
|
|
# define logf_error(fmt, ...) _logf(LOG_LEVEL_ERROR, LIT(__FILE__), __LINE__, LIT(fmt) , ## __VA_ARGS__, FMT_END)
|
|
# else
|
|
# define log_error(msg) _log(LOG_LEVEL_ERROR, msg)
|
|
# define logf_error(fmt, ...) _logf(LOG_LEVEL_ERROR, LIT(fmt) , ## __VA_ARGS__, FMT_END)
|
|
# endif
|
|
#else
|
|
# define log_error(msg)
|
|
# define logf_error(fmt, ...)
|
|
#endif
|
|
|
|
#if LOG_LEVEL(LOG_LEVEL_WARNING)
|
|
# if LOG_INCLUDE_SOURCE_LOCATION
|
|
# define log_warning(msg) _log(LOG_LEVEL_WARNING, LIT(__FILE__), __LINE__, msg)
|
|
# define logf_warning(fmt, ...) _logf(LOG_LEVEL_WARNING, LIT(__FILE__), __LINE__, LIT(fmt) , ## __VA_ARGS__, FMT_END)
|
|
# else
|
|
# define log_warning(msg) _log(LOG_LEVEL_WARNING, msg)
|
|
# define logf_warning(fmt, ...) _logf(LOG_LEVEL_WARNING, LIT(fmt) , ## __VA_ARGS__, FMT_END)
|
|
# endif
|
|
#else
|
|
# define log_warning(msg)
|
|
# define logf_warning(fmt, ...)
|
|
#endif
|
|
|
|
#if LOG_LEVEL(LOG_LEVEL_DEBUG)
|
|
# if LOG_INCLUDE_SOURCE_LOCATION
|
|
# define log_debug(msg) _log(LOG_LEVEL_DEBUG, LIT(__FILE__), __LINE__, msg)
|
|
# define logf_debug(fmt, ...) _logf(LOG_LEVEL_DEBUG, LIT(__FILE__), __LINE__, LIT(fmt) , ## __VA_ARGS__, FMT_END)
|
|
# else
|
|
# define log_debug(msg) _log(LOG_LEVEL_DEBUG, msg)
|
|
# define logf_debug(fmt, ...) _logf(LOG_LEVEL_DEBUG, LIT(fmt) , ## __VA_ARGS__, FMT_END)
|
|
# endif
|
|
#else
|
|
# define log_debug(msg)
|
|
# define logf_debug(fmt, ...)
|
|
#endif
|
|
|
|
|
|
#if LOG_LEVEL(LOG_LEVEL_INFO)
|
|
# if LOG_INCLUDE_SOURCE_LOCATION
|
|
# define log_info(msg) _log(LOG_LEVEL_INFO, LIT(__FILE__), __LINE__, msg)
|
|
# define logf_info(fmt, ...) _logf(LOG_LEVEL_INFO, LIT(__FILE__), __LINE__, LIT(fmt) , ## __VA_ARGS__, FMT_END)
|
|
# else
|
|
# define log_info(msg) _log(LOG_LEVEL_INFO, msg)
|
|
# define logf_info(fmt, ...) _logf(LOG_LEVEL_INFO, LIT(fmt) , ## __VA_ARGS__, FMT_END)
|
|
# endif
|
|
#else
|
|
# define log_info(msg)
|
|
# define logf_info(fmt, ...)
|
|
#endif
|
|
|
|
/* ========================== *
|
|
* Function declarations
|
|
* ========================== */
|
|
|
|
struct log_startup_receipt { i32 _; };
|
|
struct log_startup_receipt log_startup(struct string logfile_path);
|
|
|
|
void _log_panic(struct string msg);
|
|
|
|
#if LOG_INCLUDE_SOURCE_LOCATION
|
|
void _log(i32 level, struct string file, u32 line, struct string msg);
|
|
#else
|
|
void _log(i32 level, struct string msg);
|
|
#endif
|
|
|
|
#if LOG_INCLUDE_SOURCE_LOCATION
|
|
void _logfv(i32 level, struct string file, u32 line, struct string fmt, va_list args);
|
|
#else
|
|
void _logfv(i32 level, struct string fmt, va_list args);
|
|
#endif
|
|
|
|
#if LOG_INCLUDE_SOURCE_LOCATION
|
|
void _logf(i32 level, struct string file, u32 line, struct string fmt, ...);
|
|
#else
|
|
void _logf(i32 level, struct string fmt, ...);
|
|
#endif
|
|
|
|
#endif
|