| 1 | #include <errno.h> |
|---|---|
| 2 | #include <math/sort.h> |
| 3 | |
| 4 | static int cmp_facility_prefix(const void *key, const void *elem) { |
| 5 | uint16_t pref = *(const uint16_t *) key; |
| 6 | const struct err_facility *f = elem; |
| 7 | return (pref > f->prefix) - (pref < f->prefix); |
| 8 | } |
| 9 | |
| 10 | /* bsearch __skernel_err_facilities to __ekernel_err_facilities */ |
| 11 | static struct err_facility *facility_for(uint16_t pref) { |
| 12 | size_t count = __ekernel_err_facilities - __skernel_err_facilities; |
| 13 | return bsearch(key: &pref, base: __skernel_err_facilities, nmemb: count, |
| 14 | size: sizeof(struct err_facility), compar: cmp_facility_prefix); |
| 15 | } |
| 16 | |
| 17 | const char *errno_facility_to_str(enum errno e) { |
| 18 | uint16_t pref = ERR_GET_FACILITY(e); |
| 19 | uint16_t del = ERR_GET_DELTA(e); |
| 20 | kassert(pref && del); |
| 21 | struct err_facility *this = kassert(facility_for(pref)); |
| 22 | if (this->to_str) |
| 23 | return this->to_str(del); |
| 24 | |
| 25 | return NULL; |
| 26 | } |
| 27 | |
| 28 | void err_facilities_init() { |
| 29 | kassert(__ekernel_err_facilities - __skernel_err_facilities <= UINT16_MAX, |
| 30 | "too many?"); |
| 31 | |
| 32 | /* Simple: 1 + index in array, keeps it sorted, avoids 0 */ |
| 33 | for (struct err_facility *f = __skernel_err_facilities; |
| 34 | f < __ekernel_err_facilities; f++) |
| 35 | f->prefix = (f - __skernel_err_facilities) + 1; |
| 36 | } |
| 37 |