diff --git a/toxcore/ccompat.h b/toxcore/ccompat.h index 1ceb5a5a8..b70850d2d 100644 --- a/toxcore/ccompat.h +++ b/toxcore/ccompat.h @@ -43,9 +43,9 @@ #endif #ifdef __GNUC__ -#define GNU_PRINTF __attribute__((__format__(__printf__, 6, 7))) +#define GNU_PRINTF(f, a) __attribute__((__format__(__printf__, f, a))) #else -#define GNU_PRINTF +#define GNU_PRINTF(f, a) #endif #endif /* CCOMPAT_H */ diff --git a/toxcore/logger.c b/toxcore/logger.c index 18b765a38..80195e932 100644 --- a/toxcore/logger.c +++ b/toxcore/logger.c @@ -39,6 +39,42 @@ struct Logger { }; +static const char *logger_level_name(LOGGER_LEVEL level) +{ + switch (level) { + case LOG_TRACE: + return "TRACE"; + + case LOG_DEBUG: + return "DEBUG"; + + case LOG_INFO: + return "INFO"; + + case LOG_WARNING: + return "WARNING"; + + case LOG_ERROR: + return "ERROR"; + } + + return ""; +} + +static void logger_stderr_handler(void *context, LOGGER_LEVEL level, const char *file, int line, const char *func, + const char *message, void *userdata) +{ + // GL stands for "global logger". + fprintf(stderr, "[GL] %s %s:%d(%s): %s\n", logger_level_name(level), file, line, func, message); +} + +static const Logger logger_stderr = { + logger_stderr_handler, + nullptr, + nullptr, +}; + + /** * Public Functions */ @@ -59,10 +95,14 @@ void logger_callback_log(Logger *log, logger_cb *function, void *context, void * log->userdata = userdata; } -void logger_write(Logger *log, LOGGER_LEVEL level, const char *file, int line, const char *func, const char *format, - ...) +void logger_write(const Logger *log, LOGGER_LEVEL level, const char *file, int line, const char *func, + const char *format, ...) { - if (!log || !log->callback) { + if (!log) { + log = &logger_stderr; + } + + if (!log->callback) { return; } diff --git a/toxcore/logger.h b/toxcore/logger.h index b3a8f7dc2..2a6ee2edc 100644 --- a/toxcore/logger.h +++ b/toxcore/logger.h @@ -50,6 +50,9 @@ typedef void logger_cb(void *context, LOGGER_LEVEL level, const char *file, int */ Logger *logger_new(void); +/** + * Frees all resources associated with the logger. + */ void logger_kill(Logger *log); /** @@ -59,10 +62,16 @@ void logger_kill(Logger *log); void logger_callback_log(Logger *log, logger_cb *function, void *context, void *userdata); /** - * Main write function. If logging disabled does nothing. + * Main write function. If logging is disabled, this does nothing. + * + * If the logger is NULL, this writes to stderr. This behaviour should not be + * used in production code, but can be useful for temporarily debugging a + * function that does not have a logger available. It's essentially + * fprintf(stderr, ...), but with timestamps and source location. */ void logger_write( - Logger *log, LOGGER_LEVEL level, const char *file, int line, const char *func, const char *format, ...) GNU_PRINTF; + const Logger *log, LOGGER_LEVEL level, const char *file, int line, const char *func, + const char *format, ...) GNU_PRINTF(6, 7); #define LOGGER_WRITE(log, level, ...) \