Macros.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #ifndef HEADER_Macros
  2. #define HEADER_Macros
  3. /*
  4. htop - Macros.h
  5. (C) 2020-2023 htop dev team
  6. Released under the GNU GPLv2+, see the COPYING file
  7. in the source distribution for its full text.
  8. */
  9. #include <assert.h> // IWYU pragma: keep
  10. #include <math.h>
  11. #include <stdbool.h>
  12. #include <string.h> // IWYU pragma: keep
  13. #ifndef MINIMUM
  14. #define MINIMUM(a, b) ((a) < (b) ? (a) : (b))
  15. #endif
  16. #ifndef MAXIMUM
  17. #define MAXIMUM(a, b) ((a) > (b) ? (a) : (b))
  18. #endif
  19. #ifndef CLAMP
  20. #define CLAMP(x, low, high) (assert((low) <= (high)), ((x) > (high)) ? (high) : MAXIMUM(x, low))
  21. #endif
  22. #ifndef ARRAYSIZE
  23. #define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0]))
  24. #endif
  25. #ifndef SPACESHIP_NUMBER
  26. #define SPACESHIP_NUMBER(a, b) (((a) > (b)) - ((a) < (b)))
  27. #endif
  28. #ifndef SPACESHIP_NULLSTR
  29. #define SPACESHIP_NULLSTR(a, b) strcmp((a) ? (a) : "", (b) ? (b) : "")
  30. #endif
  31. #ifndef SPACESHIP_DEFAULTSTR
  32. #define SPACESHIP_DEFAULTSTR(a, b, s) strcmp((a) ? (a) : (s), (b) ? (b) : (s))
  33. #endif
  34. #ifdef __GNUC__ // defined by GCC and Clang
  35. #define ATTR_FORMAT(type, index, check) __attribute__((format (type, index, check)))
  36. #define ATTR_NORETURN __attribute__((noreturn))
  37. #define ATTR_UNUSED __attribute__((unused))
  38. #define ATTR_MALLOC __attribute__((malloc))
  39. #else /* __GNUC__ */
  40. #define ATTR_FORMAT(type, index, check)
  41. #define ATTR_NORETURN
  42. #define ATTR_UNUSED
  43. #define ATTR_MALLOC
  44. #endif /* __GNUC__ */
  45. #ifdef HAVE_ATTR_NONNULL
  46. #define ATTR_NONNULL __attribute__((nonnull))
  47. #define ATTR_NONNULL_N(...) __attribute__((nonnull(__VA_ARGS__)))
  48. #else
  49. #define ATTR_NONNULL
  50. #define ATTR_NONNULL_N(...)
  51. #endif /* HAVE_ATTR_NONNULL */
  52. #ifdef HAVE_ATTR_RETNONNULL
  53. #define ATTR_RETNONNULL __attribute__((returns_nonnull))
  54. #else
  55. #define ATTR_RETNONNULL
  56. #endif /* HAVE_ATTR_RETNONNULL */
  57. #ifdef HAVE_ATTR_ALLOC_SIZE
  58. #define ATTR_ALLOC_SIZE1(a) __attribute__((alloc_size (a)))
  59. #define ATTR_ALLOC_SIZE2(a, b) __attribute__((alloc_size (a, b)))
  60. #else
  61. #define ATTR_ALLOC_SIZE1(a)
  62. #define ATTR_ALLOC_SIZE2(a, b)
  63. #endif /* HAVE_ATTR_ALLOC_SIZE */
  64. #ifdef HAVE_ATTR_ACCESS
  65. #define ATTR_ACCESS2(mode, ref) __attribute__((access (mode, ref)))
  66. #define ATTR_ACCESS3(mode, ref, size) __attribute__((access (mode, ref, size)))
  67. #else
  68. #define ATTR_ACCESS2(mode, ref)
  69. #define ATTR_ACCESS3(mode, ref, size)
  70. #endif /* HAVE_ATTR_ACCESS */
  71. #define ATTR_ACCESS2_R(ref) ATTR_ACCESS2(read_only, ref)
  72. #define ATTR_ACCESS3_R(ref, size) ATTR_ACCESS3(read_only, ref, size)
  73. #define ATTR_ACCESS2_RW(ref) ATTR_ACCESS2(read_write, ref)
  74. #define ATTR_ACCESS3_RW(ref, size) ATTR_ACCESS3(read_write, ref, size)
  75. #define ATTR_ACCESS2_W(ref) ATTR_ACCESS2(write_only, ref)
  76. #define ATTR_ACCESS3_W(ref, size) ATTR_ACCESS3(write_only, ref, size)
  77. // ignore casts discarding const specifier, e.g.
  78. // const char [] -> char * / void *
  79. // const char *[2]' -> char *const *
  80. #if defined(__clang__)
  81. #define IGNORE_WCASTQUAL_BEGIN _Pragma("clang diagnostic push") \
  82. _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
  83. #define IGNORE_WCASTQUAL_END _Pragma("clang diagnostic pop")
  84. #elif defined(__GNUC__)
  85. #define IGNORE_WCASTQUAL_BEGIN _Pragma("GCC diagnostic push") \
  86. _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
  87. #define IGNORE_WCASTQUAL_END _Pragma("GCC diagnostic pop")
  88. #else
  89. #define IGNORE_WCASTQUAL_BEGIN
  90. #define IGNORE_WCASTQUAL_END
  91. #endif
  92. /* Cheaper function for checking NaNs. Unlike the standard isnan(), this may
  93. throw an FP exception on a "signaling NaN".
  94. (ISO/IEC TS 18661-1 and the C23 standard stated that isnan() throws no
  95. exceptions even with a "signaling NaN") */
  96. static inline bool isNaN(double x) {
  97. return !isgreaterequal(x, x);
  98. }
  99. /* Checks if x >= 0.0 but returns false if x is NaN. Because IEEE 754 considers
  100. -0.0 == 0.0, this function treats both zeros as nonnegative. */
  101. static inline bool isNonnegative(double x) {
  102. return isgreaterequal(x, 0.0);
  103. }
  104. /* Checks if x > 0.0 but returns false if x is NaN. */
  105. static inline bool isPositive(double x) {
  106. return isgreater(x, 0.0);
  107. }
  108. /* This subtraction is used by Linux / NetBSD / OpenBSD for calculation of CPU usage items. */
  109. static inline unsigned long long saturatingSub(unsigned long long a, unsigned long long b) {
  110. return a > b ? a - b : 0;
  111. }
  112. #endif