core.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #ifndef _LSUP_CORE_H
  2. #define _LSUP_CORE_H
  3. #include <ctype.h>
  4. #include <dirent.h>
  5. #include <errno.h>
  6. #include <inttypes.h>
  7. #include <limits.h>
  8. #include <stdbool.h>
  9. #include <stddef.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <sys/stat.h>
  14. #include <uuid/uuid.h>
  15. #ifdef DEBUG
  16. #define DEBUG_TEST 1
  17. #else
  18. #define DEBUG_TEST 0
  19. #endif
  20. #define STR "%s\n"
  21. #define TRACE(fmt, ...) \
  22. do {\
  23. if (DEBUG_TEST) \
  24. fprintf(stderr, "%s:%d:%s(): " fmt "\n", \
  25. __FILE__, __LINE__, __func__, __VA_ARGS__); \
  26. } while (0)
  27. #define LIKELY(x) __builtin_expect(!!(x), true)
  28. #define UNLIKELY(x) __builtin_expect(!!(x), false)
  29. // TODO Handle memory errors better.
  30. #define CRITICAL(exp) if (UNLIKELY ((exp) == NULL)) abort()
  31. // TODO Cross-platform ramdisk path.
  32. #define TMPDIR "/tmp"
  33. #define KLEN sizeof(LSUP_Key)
  34. #define DBL_KLEN sizeof(LSUP_DoubleKey)
  35. #define TRP_KLEN sizeof(LSUP_TripleKey)
  36. #define QUAD_KLEN sizeof(LSUP_QuadKey)
  37. # define UUIDSTR_SIZE 37
  38. // Handy flags operations.
  39. #define SET_FLAG(n, f) ((n) |= (f))
  40. #define CLR_FLAG(n, f) ((n) &= ~(f))
  41. #define TGL_FLAG(n, f) ((n) ^= (f))
  42. #define CHK_FLAG(n, f) ((n) & (f))
  43. /* * * RETURN CODES * * */
  44. /**
  45. * 0 is success, positive integers (>88800) are warnings, and negative integers
  46. * (<-88800) are errors.
  47. */
  48. typedef enum {
  49. LSUP_OK = 0,
  50. LSUP_NOACTION = 88801,
  51. LSUP_NORESULT = 88802,
  52. LSUP_END = 88803,
  53. LSUP_ERROR = -88801,
  54. LSUP_PARSE_ERR = -88802,
  55. LSUP_VALUE_ERR = -88803,
  56. LSUP_TXN_ERR = -88804,
  57. LSUP_DB_ERR = -88805,
  58. LSUP_NOT_IMPL_ERR = -88806,
  59. LSUP_IO_ERR = -88807,
  60. LSUP_MEM_ERR = -88808,
  61. } LSUP_rc;
  62. typedef enum {
  63. LSUP_BOOL_UNION,
  64. LSUP_BOOL_SUBTRACTION,
  65. LSUP_BOOL_INTERSECTION,
  66. LSUP_BOOL_XOR,
  67. } LSUP_bool_op;
  68. typedef size_t LSUP_Key;
  69. typedef LSUP_Key LSUP_DoubleKey[2];
  70. typedef LSUP_Key LSUP_TripleKey[3];
  71. typedef LSUP_Key LSUP_QuadKey[4];
  72. typedef char uuid_str_t[UUIDSTR_SIZE];
  73. // Yes, a textbook mistake; but writing min and max for all int types is crazy.
  74. #define min(x, y) (x) < (y) ? (x) : (y)
  75. #define max(x, y) (x) > (y) ? (x) : (y)
  76. /** @brief Make recursive directories.
  77. *
  78. * from https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950
  79. */
  80. LSUP_rc mkdir_p(const char *path, mode_t mode);
  81. /** @brief Remove a directory recursively, as in Unix "rm -r".
  82. *
  83. * @param path[in] Path of directory to remove.
  84. */
  85. LSUP_rc
  86. rm_r (const char *path);
  87. // Error handling via goto.
  88. #define CHECK(exp, rc, marker) (rc) = (exp); if ((rc) != LSUP_OK) goto marker
  89. // Jump if rc is negative (skip warnings).
  90. #define PCHECK(exp, rc, marker) (rc) = (exp); if ((rc) < LSUP_OK) goto marker
  91. // Return rc if it is of LSUP_rc type and is negative (=error)
  92. #define RCCK(exp) LSUP_rc _rc = (exp); if (_rc < 0) return _rc
  93. // Return NULL if it is of LSUP_rc type and is negative (=error)
  94. #define RCNL(exp) if((exp) < 0) return NULL
  95. #endif