handy.h 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. /* Normal MIN/MAX macros. Evaluate argument expressions only once. */
  12. #ifndef MIN
  13. #define MIN(x, y) \
  14. ({ typeof (x) __x = (x); \
  15. typeof (y) __y = (y); \
  16. __x < __y ? __x : __y; })
  17. #endif
  18. #ifndef MAX
  19. #define MAX(x, y) \
  20. ({ typeof (x) __x = (x); \
  21. typeof (y) __y = (y); \
  22. __x > __y ? __x : __y; })
  23. #endif
  24. /* Swap two values. Uses GCC type inference magic. */
  25. #ifndef SWAP
  26. #define SWAP(x, y) \
  27. do { \
  28. typeof (x) __tmp = (x); \
  29. (x) = (y); \
  30. (y) = __tmp; \
  31. } while (0)
  32. #endif
  33. /** Stringify its argument. */
  34. #define STRINGIFY(x) STRINGIFY_(x)
  35. #define STRINGIFY_(x) #x
  36. /* Error handling macros.
  37. *
  38. * These expect a zero = success, non-zero = error convention.
  39. */
  40. /** Error: return.
  41. *
  42. * If the expression fails, return the error from this function. */
  43. #define ER(expr) do { typeof (expr) err_ = (expr); if (err_) return err_; } while (0)
  44. /** Error: goto.
  45. *
  46. * If the expression fails, goto x_err. Assumes defn of label
  47. * x_err and 'error_type err'. */
  48. #define EG(expr) do { err = (expr); if (err) goto x_err; } while (0)
  49. /** Like memset(ptr, 0, len), but not allowed to be removed by
  50. * compilers. */
  51. static inline void mem_clean(volatile void *v, size_t len)
  52. {
  53. if (len)
  54. {
  55. memset((void *) v, 0, len);
  56. (void) *((volatile uint8_t *) v);
  57. }
  58. }
  59. /** Returns 1 if len bytes at va equal len bytes at vb, 0 if they do not.
  60. * Does not leak length of common prefix through timing. */
  61. static inline unsigned mem_eq(const void *va, const void *vb, size_t len)
  62. {
  63. const volatile uint8_t *a = va;
  64. const volatile uint8_t *b = vb;
  65. uint8_t tmp;
  66. uint8_t diff = 0;
  67. while (len--)
  68. {
  69. tmp = *b++;
  70. diff |= *a++ ^ tmp;
  71. }
  72. return !diff;
  73. }
  74. #endif