summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2012-12-04 13:26:11 +0100
committerYorhel <git@yorhel.nl>2012-12-04 13:26:11 +0100
commit82e4a8e9ebe2206b9aee96af66e945afa6b112c7 (patch)
treeed8bb4ff6ad990db4c2e94ba55f33233295941c1
parent5814a4e347928749437f121895776b2160d801fe (diff)
ecbuf: Split vars into a separate struct
This fixes a potential aliassing bug in _pop()
-rw-r--r--ecbuf.h55
1 files changed, 28 insertions, 27 deletions
diff --git a/ecbuf.h b/ecbuf.h
index e2f702b..49629fa 100644
--- a/ecbuf.h
+++ b/ecbuf.h
@@ -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