terom@8: terom@8: /* terom@8: * error handling terom@8: */ terom@8: terom@23: void _generic_err ( /*int level, */ int use_stderr, const char *func, int perr, const char *fmt, ...) terom@23: __attribute__ ((format (printf, 4, 5))); terom@19: terom@19: // needs to be defined as its own function for the noreturn attribute terom@23: void _generic_err_exit ( /* int level, */ int used_stderr, const char *func, int perr, const char *fmt, ...) terom@23: __attribute__ ((format (printf, 4, 5))) terom@19: __attribute__ ((noreturn)); terom@19: terom@20: enum _debug_level { terom@20: DEBUG_FATAL, terom@20: DEBUG_ERROR, terom@20: DEBUG_WARNING, terom@20: DEBUG_INFO, terom@20: DEBUG_DEBUG, terom@20: }; terom@20: terom@23: // not currently used terom@20: extern enum _debug_level _cur_debug_level; terom@8: terom@12: // various kinds of ways to handle an error, 2**3 of them, *g* terom@23: #define info(...) _generic_err( 0, NULL, 0, __VA_ARGS__ ) terom@23: #define error(...) _generic_err( 1, NULL, 0, __VA_ARGS__ ) terom@23: #define err_exit(...) _generic_err_exit( 1, NULL, 0, __VA_ARGS__ ) terom@23: #define perr(...) _generic_err( 1, NULL, 1, __VA_ARGS__ ) terom@23: #define perr_exit(...) _generic_err_exit( 1, NULL, 1, __VA_ARGS__ ) terom@23: #define err_func(func, ...) _generic_err( 1, func, 0, __VA_ARGS__ ) terom@23: #define err_func_exit(func, ...) _generic_err_exit( 1, func, 0, __VA_ARGS__ ) terom@23: #define perr_func(func, ...) _generic_err( 1, func, 1, __VA_ARGS__ ) terom@23: #define perr_func_exit(func, ...) _generic_err_exit( 1, func, 1, __VA_ARGS__ ) terom@11: terom@11: // error(func + colon + msg, ...) + goto error terom@12: #define ERROR(...) do { err_func(__func__, __VA_ARGS__); goto error; } while (0) terom@12: #define PERROR(...) do { perr_func(__func__, __VA_ARGS__); goto error; } while (0) terom@12: #define FATAL(...) err_func_exit(__func__, __VA_ARGS__) terom@12: #define PFATAL(...) perr_func_exit(__func__, __VA_ARGS__) terom@12: #define WARNING(...) err_func(__func__, __VA_ARGS__) terom@12: #define PWARNING(...) perr_func(__func__, __VA_ARGS__) terom@11: terom@20: #ifdef DEBUG_ENABLED terom@20: #define DEBUG(...) err_func(__func__, __VA_ARGS__) terom@20: #else terom@24: #define DEBUG(...) (void) (0) terom@20: #endif terom@20: terom@23: // default is to enable INFO terom@25: #ifdef INFO_DISABLED terom@25: #define INFO_ENABLED 0 terom@25: #else terom@25: #ifndef INFO_ENABLED terom@25: #define INFO_ENABLED 1 terom@25: #endif terom@23: #endif terom@23: terom@23: #if INFO_ENABLED terom@23: #define INFO(...) info(__VA_ARGS__) terom@23: #else terom@24: #define INFO(...) (void) (0) terom@23: #endif terom@23: