handy.h 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #ifndef HANDY_H
  2. #define HANDY_H
  3. #include <stddef.h>
  4. #include <stdint.h>
  5. #include <string.h>
  6. /*
  7. * Handy CPP defines and C inline functions.
  8. */
  9. /* Evaluates to the number of items in array-type variable arr. */
  10. #define ARRAYCOUNT(arr) (sizeof arr / sizeof arr[0])
  11. #ifndef MIN
  12. # define MIN(x, y) ((x) < (y) ? (x) : (y))
  13. #endif
  14. /** Stringify its argument. */
  15. #define STRINGIFY(x) STRINGIFY_(x)
  16. #define STRINGIFY_(x) #x
  17. /* Error handling macros.
  18. *
  19. * These expect a zero = success, non-zero = error convention.
  20. */
  21. /** Error: return.
  22. *
  23. * If the expression fails, return the error from this function. */
  24. #define ER(expr) do { typeof (expr) err_ = (expr); if (err_) return err_; } while (0)
  25. /** Error: goto.
  26. *
  27. * If the expression fails, goto x_err. Assumes defn of label
  28. * x_err and 'error_type err'. */
  29. #define EG(expr) do { err = (expr); if (err) goto x_err; } while (0)
  30. /** Like memset(ptr, 0, len), but not allowed to be removed by
  31. * compilers. */
  32. static inline void mem_clean(volatile void *v, size_t len)
  33. {
  34. if (len)
  35. {
  36. memset((void *) v, 0, len);
  37. (void) *((volatile uint8_t *) v);
  38. }
  39. }
  40. /** Returns 1 if len bytes at va equal len bytes at vb, 0 if they do not.
  41. * Does not leak length of common prefix through timing. */
  42. static inline unsigned mem_eq(const void *va, const void *vb, size_t len)
  43. {
  44. const volatile uint8_t *a = va;
  45. const volatile uint8_t *b = vb;
  46. uint8_t diff = 0;
  47. while (len--)
  48. {
  49. diff |= *a++ ^ *b++;
  50. }
  51. return !diff;
  52. }
  53. #endif