#ifndef UTIL_H #define UTIL_H #include #include #include #include #if defined(__GNUC__) || defined(__clang__) # define NORETURN __attribute__((__noreturn__)) #else # define NORETURN #endif #if defined(__GNUC__) # define UNUSED __attribute__((__unused__)) #else # define UNUSED #endif #define N_ENTRIES(x) (sizeof(x) / sizeof(*x)) #define member_size(type, member) sizeof(((type *)(0))->member) #define TYPEOF(x) __typeof__(x) #define PACKED __attribute__((__packed__)) #if defined(__GNUC__) # define FALLTHROUGH __attribute__ ((fallthrough)) #else # define FALLTHROUGH #endif NORETURN void die(const char *format, ...) __attribute__((format (printf, 1, 2))); NORETURN void die_errno(const char *format, ...) __attribute__((format (printf, 1, 2))); void err(const char * format, ...) __attribute__((format (printf, 1, 2))); void err_errno(const char * format, ...) __attribute__((format (printf, 1, 2))); #define XREALLOC_ARRAY(x, alloc) ((x) = xrealloc((x), (alloc) * sizeof(*(x)))) #define ALLOC_ARRAY(x, n) (malloc((n) * sizeof(*x))) #define ALIGN_ADDR_MASK(addr, mask) \ ((addr + ((mask) - 1)) & ~((mask) - 1)) #define ALIGN_ADDR_16(addr) ALIGN_ADDR_MASK(addr, 0x10) #define ALIGN_ADDR_32(addr) ALIGN_ADDR_MASK(addr, 0x20) #define ALIGN_ADDR_64(addr) ALIGN_ADDR_MASK(addr, 0x40) #define ALIGN_ADDR(addr, bytes) ALIGN_ADDR_MASK(addr, (8ULL*(bytes))) // Scaling: 0, 24, 66, 140, 269, 495, 890 #define ALLOC_NC(x) (((x)+14)*7/4) #define AM_RESIZE_ALLOC(buf, sz, cap, item_sz, alloc_nc) \ do { \ TYPEOF(sz) _sz = (sz); \ if((cap) < _sz) { \ void * nb; \ TYPEOF(cap) nc; \ if(_sz < alloc_nc((cap))) { \ nc = alloc_nc((cap)); \ } else { \ nc = _sz; \ } \ nb = realloc((buf), (item_sz) * nc); \ if(nb) { \ (cap) = nc; \ (buf) = nb; \ } else { \ free((buf)); \ (buf) = NULL; \ } \ } \ } while(0) #define AM_RESIZE(buf, sz, cap) \ AM_RESIZE_ALLOC(buf, sz, cap, sizeof(*buf), ALLOC_NC) #endif