damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

take.h (3419B)


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