terom@8: #ifndef LIB_LOG_H terom@8: #define LIB_LOG_H terom@1: terom@1: /* terom@1: * error handling terom@1: */ terom@1: terom@16: enum log_display_flags { terom@16: LOG_DISPLAY_STDOUT = 0x00, terom@16: LOG_DISPLAY_STDERR = 0x01, terom@16: terom@16: LOG_DISPLAY_PERR = 0x02, terom@16: terom@16: LOG_DISPLAY_NONL = 0x04, terom@27: terom@27: LOG_DISPLAY_FATAL = 0x08, terom@16: }; terom@16: terom@16: terom@16: void _generic_err (int flags, const char *func, int err, const char *fmt, ...) terom@1: __attribute__ ((format (printf, 4, 5))); terom@1: terom@1: // needs to be defined as its own function for the noreturn attribute terom@16: void _generic_err_exit (int flags, const char *func, int err, const char *fmt, ...) terom@1: __attribute__ ((format (printf, 4, 5))) terom@1: __attribute__ ((noreturn)); terom@1: terom@28: static inline void debug_dummy (int dummy, ...) { /* no-op */ } terom@28: terom@1: enum _debug_level { terom@1: DEBUG_FATAL, terom@1: DEBUG_ERROR, terom@1: DEBUG_WARNING, terom@1: DEBUG_INFO, terom@1: DEBUG_DEBUG, terom@1: }; terom@1: terom@1: // not currently used terom@1: extern enum _debug_level _cur_debug_level; terom@1: terom@1: // various kinds of ways to handle an error, 2**3 of them, *g* terom@16: #define info(...) _generic_err( LOG_DISPLAY_STDOUT, NULL, 0, __VA_ARGS__ ) terom@31: #define info_nonl(...) _generic_err( LOG_DISPLAY_STDOUT | LOG_DISPLAY_NONL, NULL, 0, __VA_ARGS__ ) terom@16: #define error(...) _generic_err( LOG_DISPLAY_STDERR, NULL, 0, __VA_ARGS__ ) terom@16: #define err_exit(...) _generic_err_exit( LOG_DISPLAY_STDERR, NULL, 0, __VA_ARGS__ ) terom@16: #define perr(...) _generic_err( LOG_DISPLAY_STDERR | LOG_DISPLAY_PERR, NULL, 0, __VA_ARGS__ ) terom@16: #define perr_exit(...) _generic_err_exit( LOG_DISPLAY_STDERR | LOG_DISPLAY_PERR, NULL, 0, __VA_ARGS__ ) terom@16: #define err_func(func, ...) _generic_err( LOG_DISPLAY_STDERR, func, 0, __VA_ARGS__ ) terom@24: #define err_func_nonl(func, ...) _generic_err( LOG_DISPLAY_STDERR | LOG_DISPLAY_NONL, func, 0, __VA_ARGS__ ) terom@16: #define err_func_exit(func, ...) _generic_err_exit( LOG_DISPLAY_STDERR, func, 0, __VA_ARGS__ ) terom@16: #define perr_func(func, ...) _generic_err( LOG_DISPLAY_STDERR | LOG_DISPLAY_PERR, func, 0, __VA_ARGS__ ) terom@16: #define perr_func_exit(func, ...) _generic_err_exit( LOG_DISPLAY_STDERR | LOG_DISPLAY_PERR, func, 0, __VA_ARGS__ ) terom@16: #define eerr_func(func, err, ...) _generic_err( LOG_DISPLAY_STDERR | LOG_DISPLAY_PERR, func, err, __VA_ARGS__ ) terom@28: #define eerr_func_exit(func,err,...) _generic_err_exit( LOG_DISPLAY_STDERR | LOG_DISPLAY_PERR, func, err, __VA_ARGS__ ) terom@16: #define debug(func, ...) _generic_err( LOG_DISPLAY_STDERR, func, 0, __VA_ARGS__ ) terom@16: #define debug_nonl(func, ...) _generic_err( LOG_DISPLAY_STDERR | LOG_DISPLAY_NONL, func, 0, __VA_ARGS__ ) terom@1: terom@16: // logging includes errors terom@8: #include "error.h" terom@8: terom@1: #define WARNING(...) err_func(__func__, __VA_ARGS__) terom@27: #define NWARNING(...) err_func_nonl(__func__, __VA_ARGS__) terom@1: #define PWARNING(...) perr_func(__func__, __VA_ARGS__) terom@2: #define EWARNING(err, ...) eerr_func(__func__, (err), __VA_ARGS__) terom@1: terom@1: #ifdef DEBUG_ENABLED terom@16: #define DEBUG(...) debug(__func__, __VA_ARGS__) terom@16: #define DEBUGF(...) debug(NULL, __VA_ARGS__) terom@16: #define DEBUGN(...) debug_nonl(__func__, __VA_ARGS__) terom@16: #define DEBUGNF(...) debug_nonl(NULL, __VA_ARGS__) terom@1: #else terom@28: #define DEBUG(...) debug_dummy(0, __VA_ARGS__) terom@28: #define DEBUGF(...) debug_dummy(0, __VA_ARGS__) terom@28: #define DEBUGN(...) debug_dummy(0, __VA_ARGS__) terom@28: #define DEBUGNF(...) debug_dummy(0, __VA_ARGS__) terom@1: #endif terom@1: terom@1: // default is to enable INFO terom@1: #ifdef INFO_DISABLED terom@1: #define INFO_ENABLED 0 terom@1: #else terom@1: #ifndef INFO_ENABLED terom@1: #define INFO_ENABLED 1 terom@1: #endif terom@1: #endif terom@1: terom@1: #if INFO_ENABLED terom@1: #define INFO(...) info(__VA_ARGS__) terom@31: #define INFON(...) info_nonl(__VA_ARGS__) terom@1: #else terom@40: #define INFO(...) debug_dummy(0, __VA_ARGS__) terom@40: #define INFON(...) debug_dummy(0, __VA_ARGS__) terom@1: #endif terom@1: terom@8: #endif /* LIB_LOG_H */