typealloclib.h (2266B)
1 #ifndef TypeAlloc_DEFS_H 2 #define TypeAlloc_DEFS_H 3 /* note - this is to make sure this overrides defs if both are included. */ 4 /* de https://github.com/notqmail/notqmail */ 5 6 #include "alloc.h" 7 #include <stdlib.h> 8 #include "error.h" 9 // needed from qmail 10 11 #include "oflops.h" 12 // unclear 13 14 #define TypeAlloc_readyplus(ta,type,field,len,a,base,ta_rplus) \ 15 static int ta_rplus ## _internal (ta *x, size_t n, size_t pluslen) \ 16 { \ 17 size_t nlen; \ 18 errno = error_nomem; \ 19 if (x->field) { \ 20 size_t nnum; \ 21 type *nfield; \ 22 if (__builtin_add_overflow(n, pluslen, &n)) \ 23 return 0; \ 24 if (n <= x->a) \ 25 return 1; \ 26 if (__builtin_add_overflow(n, (n >> 3) + base, &nnum)) \ 27 return 0; \ 28 if (__builtin_mul_overflow(nnum, sizeof(type), &nlen)) \ 29 return 0; \ 30 nfield = realloc(x->field, nlen); \ 31 if (nfield == NULL) \ 32 return 0; \ 33 x->field = nfield; \ 34 x->a = nnum; \ 35 return 1; } \ 36 x->len = 0; \ 37 if (__builtin_mul_overflow(n, sizeof(type), &nlen)) \ 38 return 0; \ 39 x->field = (type *) malloc(nlen); \ 40 if (!x->field) \ 41 return 0; \ 42 x->a = n; \ 43 return 1; } \ 44 int ta_rplus(ta *x, size_t n) \ 45 { return ta_rplus ## _internal (x, n, x->len); } 46 47 /* this needs a TypeAlloc_readyplus call before as it reuses the internal helper 48 * function. */ 49 #define TypeAlloc_ready(ta,type,field,len,a,base,ta_ready) \ 50 int ta_ready(ta *x, size_t n) \ 51 { return ta_ready ## plus_internal (x, n, 0); } 52 53 #define TypeAlloc_append(ta,type,field,len,a,base,ta_rplus,ta_append) \ 54 int ta_append(ta *x, type i) \ 55 { if (!ta_rplus(x,1)) return 0; x->field[x->len++] = i; return 1; } 56 57 #define TypeAlloc_appendentries(ta,type,field,len,a,base,ta_rplus,ta_cat) \ 58 int ta_cat(ta *x, type *i, size_t n) \ 59 { if (!ta_rplus(x,n)) return 0; for (size_t j = 0; j < n; ++j) x->field[x->len++] = *(i + j); return 1; } 60 61 // example usage -> ta_copy(saa, saa); 62 #define TypeAlloc_copy(ta,type,field,len,a,base,ta_ready,ta_copy) \ 63 int ta_copy(ta *x, ta *y) \ 64 { if (!ta_ready(x,y->len)) return 0; x->len = 0; for (size_t j = 0; j < y->len; ++j) x->field[x->len++] = *(y->field + j); return 1; } 65 66 #define TypeAlloc_free(ta,type,field,len,a,base,ta_free) \ 67 int ta_free(ta *x) \ 68 { free(x->field); x->field = NULL; x->a = x->len = 0; return 1; } 69 70 #endif