#include "../include/al/log.h" //#define AL_LOG_SKIP #define AL_LOG_TEMPLATE "%s:%d %s(): %s -> " #define AL_LOG_TEMPLATE_SECTION AL_LOG_TEMPLATE"(%s) " #define AL_LOG_MESSAGE_MAX ((size_t)(AL_LOG_MESSAGE_SIZE - 1u)) // Space for newline. #ifndef AL_FORCE_DISABLE_OUTPUT static s32 (*_al_print)(void *, u8, char *) = NULL; static void *_al_log_userdata = NULL; void al_set_print(s32 (*print_func)(void *, u8, char *), void *userdata) { _al_print = print_func; _al_log_userdata = userdata; } static const char *levels[] = { [AL_LOG_INFO] = "info", [AL_LOG_WARN] = "warn", [AL_LOG_ERROR] = "error", [AL_LOG_DEBUG] = "debug", [AL_LOG_TRACE] = "trace" }; #ifndef AL_LOG_SKIP static __thread char messagebuf[AL_LOG_MESSAGE_SIZE]; static char *get_message_buffer(u8 level, const char *section, const char *name, const s32 line, const char *func, const char *fmt, va_list args) { s32 prefix = 0; if (!section) { prefix = al_snprintf(messagebuf, AL_LOG_MESSAGE_MAX, AL_LOG_TEMPLATE, name, line, func, levels[level]); } else { prefix = al_snprintf(messagebuf, AL_LOG_MESSAGE_MAX, AL_LOG_TEMPLATE_SECTION, name, line, func, levels[level], section); } al_assert(prefix > 0); al_vsnprintf(messagebuf + prefix, AL_LOG_MESSAGE_MAX - (size_t)prefix, fmt, args); messagebuf[strcspn(messagebuf, "\r\n")] = '\0'; return messagebuf; } #endif s32 _al_logv(u8 level, const char *section, const char *name, const s32 line, const char *func, const char *fmt, va_list args) { #ifdef AL_LOG_SKIP s32 ret = 0; if (!section) { ret += al_printf(AL_LOG_TEMPLATE, name, line, func, levels[level]); } else { ret += al_printf(AL_LOG_TEMPLATE_SECTION, name, line, func, levels[level], section); } ret += al_vprintf(fmt, args); if (strcspn(fmt, "\r\n") == al_strlen(fmt)) { ret += al_printf("\n"); } return ret; #else al_assert(_al_print && "Global print method not set."); return _al_print(_al_log_userdata, level, get_message_buffer(level, section, name, line, func, fmt, args)); #endif } s32 _al_log(u8 level, const char *section, const char *name, const s32 line, const char *func, const char *fmt, ...) { va_list args; va_start(args, fmt); s32 ret = _al_logv(level, section, name, line, func, fmt, args); va_end(args); return ret; } #else void al_set_print(s32 (*print_func)(void *, u8, char *), void *userdata) { (void)print_func; (void)userdata; } s32 _al_logv(u8 level, const char *section, const char *name, const s32 line, const char *func, const char *fmt, va_list args) { (void)level; (void)section; (void)name; (void)line; (void)func; (void)fmt; (void)args; return 0; } s32 _al_log(u8 level, const char *section, const char *name, const s32 line, const char *func, const char *fmt, ...) { (void)level; (void)section; (void)name; (void)line; (void)func; (void)fmt; return 0; } #endif