take.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /* CC0 (Public domain) - see LICENSE file for details */
  2. #ifndef CCAN_TAKE_H
  3. #define CCAN_TAKE_H
  4. #include "config.h"
  5. #include <stdbool.h>
  6. #include <ccan/str/str.h>
  7. #ifdef CCAN_TAKE_DEBUG
  8. #define TAKE_LABEL(p) __FILE__ ":" stringify(__LINE__) ":" stringify(p)
  9. #else
  10. #define TAKE_LABEL(p) NULL
  11. #endif
  12. /**
  13. * TAKES - annotate a formal parameter as being take()-able
  14. *
  15. * This doesn't do anything, but useful for documentation.
  16. *
  17. * Example:
  18. * void print_string(const char *str TAKES);
  19. *
  20. */
  21. #define TAKES
  22. /**
  23. * take - record a pointer to be consumed by the function its handed to.
  24. * @p: the pointer to mark, or NULL.
  25. *
  26. * This marks a pointer object to be freed by the called function,
  27. * which is extremely useful for chaining functions. It works on
  28. * NULL, for pass-through error handling.
  29. */
  30. #define take(p) (take_typeof(p) take_((p), TAKE_LABEL(p)))
  31. /**
  32. * taken - check (and un-take) a pointer was passed with take()
  33. * @p: the pointer to check.
  34. *
  35. * A function which accepts take() arguments uses this to see if it
  36. * should own the pointer; it will be removed from the take list, so
  37. * this only returns true once.
  38. *
  39. * Example:
  40. * // Silly routine to add 1
  41. * static int *add_one(const int *num TAKES)
  42. * {
  43. * int *ret;
  44. * if (taken(num))
  45. * ret = (int *)num;
  46. * else
  47. * ret = malloc(sizeof(int));
  48. * if (ret)
  49. * *ret = (*num) + 1;
  50. * return ret;
  51. * }
  52. */
  53. bool taken(const void *p);
  54. /**
  55. * is_taken - check if a pointer was passed with take()
  56. * @p: the pointer to check.
  57. *
  58. * This is like the above, but doesn't remove it from the taken list.
  59. *
  60. * Example:
  61. * // Silly routine to add 1: doesn't handle taken args!
  62. * static int *add_one_notake(const int *num)
  63. * {
  64. * int *ret = malloc(sizeof(int));
  65. * assert(!is_taken(num));
  66. * if (ret)
  67. * *ret = (*num) + 1;
  68. * return ret;
  69. * }
  70. */
  71. bool is_taken(const void *p);
  72. /**
  73. * taken_any - are there any taken pointers?
  74. *
  75. * Mainly useful for debugging take() leaks. With CCAN_TAKE_DEBUG, returns
  76. * the label where the pointer was passed to take(), otherwise returns
  77. * a static char buffer with the pointer value in it. NULL if none are taken.
  78. *
  79. * Example:
  80. * static void cleanup(void)
  81. * {
  82. * assert(!taken_any());
  83. * }
  84. */
  85. const char *taken_any(void);
  86. /**
  87. * take_cleanup - remove all taken pointers from list.
  88. *
  89. * This is useful in atexit() handlers for valgrind-style leak detection.
  90. *
  91. * Example:
  92. * static void cleanup2(void)
  93. * {
  94. * take_cleanup();
  95. * }
  96. */
  97. void take_cleanup(void);
  98. /**
  99. * take_allocfail - set function to call if we can't reallocated taken array.
  100. * @fn: the function.
  101. *
  102. * If this is not set, then if the array reallocation fails, the
  103. * pointer won't be marked taken(). If @fn returns, it is expected to
  104. * free the pointer; we return NULL from take() and the function handles
  105. * it like any allocation failure.
  106. *
  107. * Example:
  108. * static void free_on_fail(const void *p)
  109. * {
  110. * free((void *)p);
  111. * }
  112. *
  113. * static void init(void)
  114. * {
  115. * take_allocfail(free_on_fail);
  116. * }
  117. */
  118. void take_allocfail(void (*fn)(const void *p));
  119. /* Private functions */
  120. #if HAVE_TYPEOF
  121. #define take_typeof(ptr) (__typeof__(ptr))
  122. #else
  123. #define take_typeof(ptr)
  124. #endif
  125. void *take_(const void *p, const char *label);
  126. #endif /* CCAN_TAKE_H */