nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

typealloclib.h (2268B)


      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