#ifndef HANDY_H #define HANDY_H #include #include #include /* * Handy CPP defines and C inline functions. */ /* Evaluates to the number of items in array-type variable arr. */ #define ARRAYCOUNT(arr) (sizeof arr / sizeof arr[0]) #ifndef MIN # define MIN(x, y) ((x) < (y) ? (x) : (y)) #endif /** Stringify its argument. */ #define STRINGIFY(x) STRINGIFY_(x) #define STRINGIFY_(x) #x /* Error handling macros. * * These expect a zero = success, non-zero = error convention. */ /** Error: return. * * If the expression fails, return the error from this function. */ #define ER(expr) do { typeof (expr) err_ = (expr); if (err_) return err_; } while (0) /** Error: goto. * * If the expression fails, goto x_err. Assumes defn of label * x_err and 'error_type err'. */ #define EG(expr) do { err = (expr); if (err) goto x_err; } while (0) /** Like memset(ptr, 0, len), but not allowed to be removed by * compilers. */ static inline void mem_clean(volatile void *v, size_t len) { if (len) { memset((void *) v, 0, len); (void) *((volatile uint8_t *) v); } } /** Returns 1 if len bytes at va equal len bytes at vb, 0 if they do not. * Does not leak length of common prefix through timing. */ static inline unsigned mem_eq(const void *va, const void *vb, size_t len) { const volatile uint8_t *a = va; const volatile uint8_t *b = vb; uint8_t diff = 0; while (len--) { diff |= *a++ ^ *b++; } return !diff; } #endif