diff options
author | Yorhel <git@yorhel.nl> | 2012-12-04 13:26:11 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2012-12-04 13:26:11 +0100 |
commit | 82e4a8e9ebe2206b9aee96af66e945afa6b112c7 (patch) | |
tree | ed8bb4ff6ad990db4c2e94ba55f33233295941c1 | |
parent | 5814a4e347928749437f121895776b2160d801fe (diff) |
ecbuf: Split vars into a separate struct
This fixes a potential aliassing bug in _pop()
-rw-r--r-- | ecbuf.h | 55 |
1 files changed, 28 insertions, 27 deletions
@@ -68,48 +68,49 @@ * cn: Number of slots in the cirbular buffer * bn: Number of slots in the complete buffer */ +typedef struct { + int l, o, b, cn, bn; +} ecbuf_vars_t; + #define ecbuf_t(type) struct {\ - int l, o, b, cn, bn;\ + ecbuf_vars_t v;\ type *a;\ } -/* Internal type for use with ecbuf__pop() */ -typedef ecbuf_t(void) ecbuf__t; - -#define ecbuf_init(v) do {\ - (v).bn = (v).cn = 32;\ - (v).o = (v).l = 0;\ - (v).b = -1;\ - (v).a = malloc((v).bn*sizeof(*(v).a));\ +#define ecbuf_init(e) do {\ + (e).v.bn = (e).v.cn = 32;\ + (e).v.o = (e).v.l = 0;\ + (e).v.b = -1;\ + (e).a = malloc((e).v.bn*sizeof(*(e).a));\ } while(0) -#define ecbuf_destroy(v) free((v).a) +#define ecbuf_destroy(e) free((e).a) /* Number of items queued. */ -#define ecbuf_len(v) ((v).l) +#define ecbuf_len(e) ((e).v.l) -#define ecbuf_empty(v) (ecbuf_len(v) == 0) +#define ecbuf_empty(e) (ecbuf_len(e) == 0) /* Peek into the queue, requires !ecbuf_empty(v) */ -#define ecbuf_peek(v) ((v).a[(v).o]) - -#define ecbuf_push(v, x) do {\ - if((v).l == (v).bn) {\ - if((v).cn == (v).bn)\ - (v).b = ((v).o - 1 + (v).cn) & ((v).cn-1);\ - (v).bn <<= 1;\ - (v).a = realloc((v).a, (v).bn*sizeof(*(v).a));\ +#define ecbuf_peek(e) ((e).a[(e).v.o]) + +#define ecbuf_push(e, x) do {\ + if((e).v.l == (e).v.bn) {\ + if((e).v.cn == (e).v.bn)\ + (e).v.b = ((e).v.o - 1 + (e).v.cn) & ((e).v.cn-1);\ + (e).v.bn <<= 1;\ + (e).a = realloc((e).a, (e).v.bn*sizeof(*(e).a));\ }\ - int _ecbuf_i = (v).l + (v).o - (v).b - 1;\ - if((v).bn == (v).cn) _ecbuf_i &= (v).cn-1;\ - else if((v).o <= (v).b) _ecbuf_i += (v).cn;\ - (v).l++;\ - (v).a[_ecbuf_i] = (x);\ + int _ecbuf_i = (e).v.l + (e).v.o - (e).v.b - 1;\ + if((e).v.bn == (e).v.cn) _ecbuf_i &= (e).v.cn-1;\ + else if((e).v.o <= (e).v.b) _ecbuf_i += (e).v.cn;\ + (e).v.l++;\ + (e).a[_ecbuf_i] = (x);\ } while(0) -static inline int ecbuf__pop(ecbuf__t *v) { +static inline int ecbuf__pop(ecbuf_vars_t *v) { int l = v->o; v->l--; if(v->o == v->b) { @@ -122,7 +123,7 @@ static inline int ecbuf__pop(ecbuf__t *v) { v->o++; return l; } -#define ecbuf_pop(v) ((v).a[ecbuf__pop((ecbuf__t *)&(v))]) +#define ecbuf_pop(e) ((e).a[ecbuf__pop(&(e).v)]) #endif |