core.h 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #ifndef _LSUP_CORE_H
  2. #define _LSUP_CORE_H
  3. #include <ctype.h>
  4. #include <inttypes.h>
  5. #include <stdbool.h>
  6. #include <stddef.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <uuid/uuid.h>
  11. #ifdef DEBUG
  12. #define DEBUG_TEST 1
  13. #else
  14. #define DEBUG_TEST 0
  15. #endif
  16. #define STR "%s\n"
  17. #define TRACE(fmt, ...) \
  18. do {\
  19. if (DEBUG_TEST) \
  20. fprintf(stderr, "%s:%d:%s(): " fmt "\n", \
  21. __FILE__, __LINE__, __func__, __VA_ARGS__); \
  22. } while (0)
  23. #define LIKELY(x) __builtin_expect(!!(x), true)
  24. #define UNLIKELY(x) __builtin_expect(!!(x), false)
  25. // TODO Handle memory errors better.
  26. #define CRITICAL(exp) if (UNLIKELY(((exp) == NULL))) { abort(); }
  27. #define KLEN sizeof(LSUP_Key)
  28. #define DBL_KLEN sizeof(LSUP_DoubleKey)
  29. #define TRP_KLEN sizeof(LSUP_TripleKey)
  30. #define QUAD_KLEN sizeof(LSUP_QuadKey)
  31. # define UUIDSTR_SIZE 37
  32. // Handy flags operations.
  33. #define SET_FLAG(n, f) ((n) |= (f))
  34. #define CLR_FLAG(n, f) ((n) &= ~(f))
  35. #define TGL_FLAG(n, f) ((n) ^= (f))
  36. #define CHK_FLAG(n, f) ((n) & (f))
  37. /* * * RETURN CODES * * */
  38. /**
  39. * 0 is success, positive integers (>88800) are warnings, and negative integers
  40. * (<-88800) are errors.
  41. */
  42. typedef enum {
  43. LSUP_OK = 0,
  44. LSUP_NOACTION = 88801,
  45. LSUP_NORESULT = 88802,
  46. LSUP_END = 88803,
  47. LSUP_ERROR = -88801,
  48. LSUP_PARSE_ERR = -88802,
  49. LSUP_VALUE_ERR = -88803,
  50. LSUP_TXN_ERR = -88804,
  51. } LSUP_rc;
  52. typedef size_t LSUP_Key;
  53. typedef LSUP_Key LSUP_DoubleKey[2];
  54. typedef LSUP_Key LSUP_TripleKey[3];
  55. typedef LSUP_Key LSUP_QuadKey[4];
  56. typedef char uuid_str_t[UUIDSTR_SIZE];
  57. // Don't use MIN and MAX macros: see
  58. // https://dustri.org/b/min-and-max-macro-considered-harmful.html
  59. inline int min(int x, int y) { return x < y ? x : y; }
  60. inline int max(int x, int y) { return x > y ? x : y; }
  61. // Error handling via goto.
  62. #define CHECK(exp, marker) rc = (exp); if (rc != LSUP_OK) goto marker
  63. // Jump if rc is negative (skip warnings).
  64. #define PCHECK(exp, marker) rc = (exp); if (rc < LSUP_OK) goto marker
  65. // Check against a list of allowed return codes.
  66. // If none match, jump to marker.
  67. #define MCHECK(exp, allowed, marker) \
  68. rc = (exp); \
  69. bool jump = true; \
  70. for(int i = 0; i < sizeof(allowed) / sizeof(int); i++) { \
  71. if (rc == allowed[i]) { \
  72. jump = false; \
  73. break; \
  74. } \
  75. } \
  76. if (jump) goto marker; \
  77. #endif