/* Public domain. */ #ifndef GEN_ALLOC_H #define GEN_ALLOC_H #include "alloc.h" /* .h */ #define GEN_ALLOC_ZERO { 0, 0, 0 } #define GEN_ALLOC_typedef(ta, type, s, len, a) \ typedef struct ta { type *s ; unsigned int len ; unsigned int a ; } ta, *ta##_ref ; #define GEN_ALLOC_FPROTOTYPES(ta, type, s, len, a) \ extern int ta##_ready (ta *, unsigned int) ; \ extern int ta##_readyplus (ta *, unsigned int) ; \ extern void ta##_free (ta *) ; \ extern void ta##_clean (ta *) ; \ extern int ta##_copyb (ta *, type const *, unsigned int) ; \ extern int ta##_copy (ta *, ta const *) ; \ extern int ta##_catb (ta *, type const *, unsigned int) ; \ extern int ta##_cat (ta *, ta const *) ; \ extern int ta##_append (ta *, type const *) ; \ extern void ta##_reverse (ta *) ; \ extern void ta##_zerolen (ta *) ; \ extern void ta##_deepfree (ta *) ; \ #define GEN_ALLOC_PROTOTYPES(ta, type, s, len, a) \ GEN_ALLOC_typedef(ta, type, s, len, a) \ GEN_ALLOC_FPROTOTYPES(ta, type, s, len, a) \ /* .c */ #define GEN_ALLOC_ready(ta, type, s, len, a, base) \ int ta##_ready (register ta *x, register unsigned int n) \ { \ if (!x->s) return !!(x->s = (type *)alloc((x->a = n) * sizeof(type))) ; \ if (n > x->a) \ { \ register unsigned int t = (base) + n + (n >> 3) ; \ if (!alloc_re((void **)(void *)(&x->s), x->a * sizeof(type), t * sizeof(type))) \ return 0 ; \ x->a = t ; \ } \ return 1 ; \ } \ #define GEN_ALLOC_readyplus(ta, type, s, len, a) \ int ta##_readyplus (register ta *x, register unsigned int n) \ { \ return ta##_ready(x, n + x->len) ; \ } \ #define GEN_ALLOC_free(ta, type, s, len, a) \ void ta##_free (register ta *x) \ { \ alloc_free(x->s) ; x->s = 0 ; \ x->a = x->len = 0 ; \ } \ #define GEN_ALLOC_clean(ta, type, s, len, a) \ void ta##_clean (register ta *x) \ { \ if (x->a > x->len) \ { \ alloc_realloc((void **)(void *)(&x->s), x->len * sizeof(type)) ; \ x->a = x->len ; \ } \ } \ #define GEN_ALLOC_copyb(ta, type, s, len, a) \ int ta##_copyb (register ta *sa, register type const *x, unsigned int n) \ { \ if (!ta##_ready(sa, n)) return 0 ; \ { \ unsigned int i = 0 ; \ for ( ; i < n ; i++) sa->s[i] = x[i] ; \ } \ sa->len = n ; \ return 1 ; \ } \ #define GEN_ALLOC_copy(ta, type, s, len, a) \ int ta##_copy (register ta *to, register ta const *from) \ { \ return ta##_copyb(to, from->s, from->len) ; \ } \ #define GEN_ALLOC_catb(ta, type, s, len, a) \ int ta##_catb (register ta *sa, register type const *x, unsigned int n) \ { \ if (!ta##_readyplus(sa, n)) return 0 ; \ { \ unsigned int i = 0 ; \ for ( ; i < n ; i++) sa->s[sa->len + i] = x[i] ; \ } \ sa->len += n ; \ return 1 ; \ } \ #define GEN_ALLOC_cat(ta, type, s, len, a) \ int ta##_cat (register ta *to, register ta const *from) \ { \ return ta##_catb(to, from->s, from->len) ; \ } \ #define GEN_ALLOC_append(ta, type, s, len, a) \ int ta##_append (register ta *x, register type const *i) \ { \ return ta##_catb(x, i, 1) ; \ } \ #define GEN_ALLOC_reverse(ta, type, s, len, a) \ void ta##_reverse (register ta *x) \ { \ register unsigned int i = 0 ; \ for (; i < (x->len) >> 1 ; i++) \ { \ type tmp = x->s[i] ; \ x->s[i] = x->s[x->len - 1 - i] ; \ x->s[x->len - 1 - i] = tmp ; \ } \ } \ #define GEN_ALLOC_BASE_DEFS(ta, type, s, len, a, base) \ GEN_ALLOC_ready(ta, type, s, len, a, base) \ GEN_ALLOC_readyplus(ta, type, s, len, a) \ GEN_ALLOC_free(ta, type, s, len, a) \ GEN_ALLOC_catb(ta, type, s, len, a) \ #define GEN_ALLOC_STATIC_BASE_DEFS(ta, type, s, len, a, base) \ static GEN_ALLOC_ready(ta, type, s, len, a, base) \ static GEN_ALLOC_readyplus(ta, type, s, len, a) \ static GEN_ALLOC_free(ta, type, s, len, a) \ static GEN_ALLOC_catb(ta, type, s, len, a) \ #define GEN_ALLOC_EXTENDED_DEFS(ta, type, s, len, a) \ GEN_ALLOC_clean(ta, type, s, len, a) \ GEN_ALLOC_copyb(ta, type, s, len, a) \ GEN_ALLOC_copy(ta, type, s, len, a) \ GEN_ALLOC_cat(ta, type, s, len, a) \ GEN_ALLOC_append(ta, type, s, len, a) \ GEN_ALLOC_reverse(ta, type, s, len, a) \ #define GEN_ALLOC_STATIC_EXTENDED_DEFS(ta, type, s, len, a) \ static GEN_ALLOC_clean(ta, type, s, len, a) \ static GEN_ALLOC_copyb(ta, type, s, len, a) \ static GEN_ALLOC_copy(ta, type, s, len, a) \ static GEN_ALLOC_cat(ta, type, s, len, a) \ static GEN_ALLOC_append(ta, type, s, len, a) \ static GEN_ALLOC_reverse(ta, type, s, len, a) \ #define GEN_ALLOC_DEFS(ta, type, s, len, a, base) \ GEN_ALLOC_BASE_DEFS(ta, type, s, len, a, base) \ GEN_ALLOC_EXTENDED_DEFS(ta, type, s, len, a) \ #define GEN_ALLOC_STATIC_DEFS(ta, type, s, len, a, base) \ GEN_ALLOC_STATIC_BASE_DEFS(ta, type, s, len, a, base) \ GEN_ALLOC_STATIC_EXTENDED_DEFS(ta, type, s, len, a) \ #endif