struct err_facility {
uint16_t prefix;
const char *name;
const char *desc;
const char *(*const to_str)(uint16_t delta);
};
enum errno {
ERR_OK = 0,
ERR_UNKNOWN = -1,
ERR_NO_MEM = -2,
ERR_NO_DEV = -3,
ERR_NO_ENT = -4,
ERR_EXIST = -5,
ERR_IO = -6,
ERR_NOT_DIR = -7,
ERR_IS_DIR = -8,
ERR_INVAL = -9,
ERR_PERM = -10,
ERR_FAULT = -11,
ERR_BUSY = -12,
ERR_AGAIN = -13,
ERR_NOT_IMPL = -14,
ERR_NOSPC = -15,
ERR_OVERFLOW = -16,
ERR_NOT_EMPTY = -17,
};
const char * errno_facility_to_str(enum errno err);
void err_facilities_init();
char errno_to_str(enum errno err);
#define ERR_IS_FATAL(e) (e != ERR_OK && e != ERR_AGAIN)
#define ERR_IS_MATCH_1(v, a) ((v) == (a))
#define ERR_IS_MATCH_2(v, a, b) (ERR_IS_MATCH_1(v, a) || ((v) == (b)))
#define ERR_IS_MATCH_3(v, a, b, c) (ERR_IS_MATCH_2(v, a, b) || ((v) == (c)))
#define ERR_IS_MATCH_4(v, a, b, c, d) \
(ERR_IS_MATCH_3(v, a, b, c) || ((v) == (d)))
#define ERR_IS_MATCH_5(v, a, b, c, d, e) \
(ERR_IS_MATCH_4(v, a, b, c, d) || ((v) == (e)))
#define ERR_IS_MATCH_6(v, a, b, c, d, e, f) \
(ERR_IS_MATCH_5(v, a, b, c, d, e) || ((v) == (f)))
#define ERR_IS_MATCH_7(v, a, b, c, d, e, f, g) \
(ERR_IS_MATCH_6(v, a, b, c, d, e, f) || ((v) == (g)))
#define ERR_IS_MATCH_8(v, a, b, c, d, e, f, g, h) \
(ERR_IS_MATCH_7(v, a, b, c, d, e, f, g) || ((v) == (h)))
#define ERR_GUARD(val, ...) \
({ \
__auto_type _v = (val); \
if (unlikely(_v < 0 && !_DISPATCH(ERR_IS_MATCH, PP_NARG(__VA_ARGS__))( \
_v, __VA_ARGS__))) \
panic("unhandled error: %s", errno_to_str(_v)); \
_v; \
})
#define ERR_CREATE(pre, del) \
({ \
kassert((del & 0xFFFF) == del); \
kassert(del > 0); \
-((((int) (pre)) << 16) | (((int) (del)) & 0xFFFF)); \
})
#define ERR_GET_FACILITY(e) \
({ \
kassert(e < 0); \
((-(e)) >> 16) & 0xFFFF; \
})
#define ERR_GET_DELTA(e) \
({ \
kassert(e < 0); \
((-(e)) & 0xFFFF); \
})
#define ERR_PREFIX(n) ((__err_facility_##n).prefix)
#define ERR_DELTA_START (1)
#define ERR(n, d) ERR_CREATE(ERR_PREFIX(n), d)
#define ERR_FACILITY(n) __err_facility_##n
#define ERR_FACILITY_EXTERN(n) extern struct err_facility __err_facility_##n
#define ERR_FACILITY_DECLARE(n, ...) \
LINKER_SECTION_OBJECT(struct err_facility, err_facilities) \
__err_facility_##n = {.name = #n, __VA_ARGS__}