We often need to return the same message over and over again with the same return value. Use default log-messages now instead of ignoring the log. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
181 lines
6.0 KiB
C
181 lines
6.0 KiB
C
/*
|
|
* Library Log/Debug Interface
|
|
* Copyright (c) 2012 David Herrmann <dh.herrmann@googlemail.com>
|
|
* Dedicated to the Public Domain
|
|
*/
|
|
|
|
/*
|
|
* Library Log/Debug Interface
|
|
* Libraries should always avoid producing side-effects. This includes writing
|
|
* log-messages of any kind. However, you often don't want to disable debugging
|
|
* entirely, therefore, the core objects often contain a pointer to a function
|
|
* which performs logging. If that pointer is NULL (default), logging is
|
|
* disabled.
|
|
*
|
|
* This header should never be installed into the system! This is _no_ public
|
|
* header. Instead, copy it into your application if you want and use it there.
|
|
* Your public library API should include something like this:
|
|
*
|
|
* typedef void (*MYPREFIX_log_t) (const char *file,
|
|
* int line,
|
|
* const char *func,
|
|
* const char *subs,
|
|
* unsigned int sev,
|
|
* const char *format,
|
|
* va_list args);
|
|
*
|
|
* And then the user can supply such a function when creating a new context
|
|
* object of your library or simply supply NULL. Internally, you have a field of
|
|
* type "MYPREFIX_log_t llog" in your main structure. If you pass this to the
|
|
* convenience helpers like llog_dbg(), llog_warn() etc. it will automatically
|
|
* use the "llog" field to print the message. If it is NULL, nothing is done.
|
|
*
|
|
* The arguments of the log-function are defined as:
|
|
* file: Zero terminated string of the file-name where the log-message
|
|
* occurred. Can be NULL.
|
|
* line: Line number of @file where the message occurred. Set to 0 or smaller
|
|
* if not available.
|
|
* func: Function name where the log-message occurred. Can be NULL.
|
|
* subs: Subsystem where the message occurred (zero terminated). Can be NULL.
|
|
* sev: Severity of log-message. An integer between 0 and 7 as defined below.
|
|
* These are identical to the linux-kernel severities so there is no need
|
|
* to include these in your public API. Every app can define them
|
|
* themself, if they need it.
|
|
* format: Format string. Must not be NULL.
|
|
* args: Argument array
|
|
*/
|
|
|
|
#ifndef LLOG_H_INCLUDED
|
|
#define LLOG_H_INCLUDED
|
|
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
|
|
enum llog_severity {
|
|
LLOG_FATAL = 0,
|
|
LLOG_ALERT = 1,
|
|
LLOG_CRITICAL = 2,
|
|
LLOG_ERROR = 3,
|
|
LLOG_WARNING = 4,
|
|
LLOG_NOTICE = 5,
|
|
LLOG_INFO = 6,
|
|
LLOG_DEBUG = 7,
|
|
LLOG_SEV_NUM,
|
|
};
|
|
|
|
typedef void (*llog_submit_t) (const char *file,
|
|
int line,
|
|
const char *func,
|
|
const char *subs,
|
|
unsigned int sev,
|
|
const char *format,
|
|
va_list args);
|
|
|
|
static void llog_format(llog_submit_t llog,
|
|
const char *file,
|
|
int line,
|
|
const char *func,
|
|
const char *subs,
|
|
unsigned int sev,
|
|
const char *format,
|
|
...)
|
|
{
|
|
va_list list;
|
|
|
|
if (llog) {
|
|
va_start(list, format);
|
|
llog(file, line, func, subs, sev, format, list);
|
|
va_end(list);
|
|
}
|
|
}
|
|
|
|
#ifndef LLOG_SUBSYSTEM
|
|
static const char *LLOG_SUBSYSTEM __attribute__((__unused__));
|
|
#endif
|
|
|
|
#define LLOG_DEFAULT __FILE__, __LINE__, __func__, LLOG_SUBSYSTEM
|
|
|
|
#define llog_printf(obj, sev, format, ...) \
|
|
llog_format((obj)->llog, LLOG_DEFAULT, (sev), (format), ##__VA_ARGS__)
|
|
#define llog_dprintf(obj, sev, format, ...) \
|
|
llog_format((obj), LLOG_DEFAULT, (sev), (format), ##__VA_ARGS__)
|
|
|
|
/*
|
|
* Helpers
|
|
* They pick-up all the default values and submit the message to the
|
|
* llog-subsystem. The llog_debug() function produces zero-code if
|
|
* LLOG_ENABLE_DEBUG is not defined. Therefore, it can be heavily used for
|
|
* debugging and will not have any side-effects.
|
|
*/
|
|
|
|
#ifdef LLOG_ENABLE_DEBUG
|
|
#define llog_ddebug(obj, format, ...) \
|
|
llog_dprintf((obj), LLOG_DEBUG, (format), ##__VA_ARGS__)
|
|
#define llog_debug(obj, format, ...) \
|
|
llog_ddebug((obj)->llog, (format), ##__VA_ARGS__)
|
|
#else
|
|
#define llog_ddebug(obj, format, ...)
|
|
#define llog_debug(obj, format, ...)
|
|
#endif
|
|
|
|
#define llog_info(obj, format, ...) \
|
|
llog_printf((obj), LLOG_INFO, (format), ##__VA_ARGS__)
|
|
#define llog_notice(obj, format, ...) \
|
|
llog_printf((obj), LLOG_NOTICE, (format), ##__VA_ARGS__)
|
|
#define llog_warning(obj, format, ...) \
|
|
llog_printf((obj), LLOG_WARNING, (format), ##__VA_ARGS__)
|
|
#define llog_error(obj, format, ...) \
|
|
llog_printf((obj), LLOG_ERROR, (format), ##__VA_ARGS__)
|
|
#define llog_critical(obj, format, ...) \
|
|
llog_printf((obj), LLOG_CRITICAL, (format), ##__VA_ARGS__)
|
|
#define llog_alert(obj, format, ...) \
|
|
llog_printf((obj), LLOG_ALERT, (format), ##__VA_ARGS__)
|
|
#define llog_fatal(obj, format, ...) \
|
|
llog_printf((obj), LLOG_FATAL, (format), ##__VA_ARGS__)
|
|
|
|
#define llog_dbg llog_debug
|
|
#define llog_warn llog_warning
|
|
#define llog_err llog_error
|
|
#define llog_crit llog_critical
|
|
|
|
/*
|
|
* Default log messages
|
|
* These macros can be used to produce default log messages. You can use them
|
|
* directly in an "return" statement. The "v" variants automatically cast the
|
|
* result to void so it can be used in return statements inside of void
|
|
* functions. The "d" variants use the logging object directly as the parent
|
|
* might not exist, yet.
|
|
*
|
|
* Most of the messages work only if debugging is enabled. This is, because they
|
|
* are used in debug paths and would slow down normal applications.
|
|
*/
|
|
|
|
#define llog_dEINVAL(obj) \
|
|
(llog_ddebug((obj), "invalid arguments"), -EINVAL)
|
|
#define llog_EINVAL(obj) \
|
|
(llog_dEINVAL((obj)->llog))
|
|
#define llog_vEINVAL(obj) \
|
|
((void)llog_EINVAL(obj))
|
|
#define llog_vdEINVAL(obj) \
|
|
((void)llog_dEINVAL(obj))
|
|
|
|
#define llog_dEFAULT(obj) \
|
|
(llog_ddebug((obj), "operation failed"), -EFAULT)
|
|
#define llog_EFAULT(obj) \
|
|
(llog_dEFAULT((obj)->llog))
|
|
#define llog_vEFAULT(obj) \
|
|
((void)llog_EFAULT(obj))
|
|
#define llog_vdEFAULT(obj) \
|
|
((void)llog_dEFAULT(obj))
|
|
|
|
#define llog_dENOMEM(obj) \
|
|
(llog_ddebug((obj), "memory allocation failed"), -ENOMEM)
|
|
#define llog_ENOMEM(obj) \
|
|
(llog_dENOMEM((obj)->llog))
|
|
#define llog_vENOMEM(obj) \
|
|
((void)llog_ENOMEM(obj))
|
|
#define llog_vdENOMEM(obj) \
|
|
((void)llog_dENOMEM(obj))
|
|
|
|
#endif /* LLOG_H_INCLUDED */
|