commit 4ba2b388903f6177d3e2f0d218213f2ffe21b99c
parent 8685019dec16117683b84e39aad98a502d4128e7
Author: Amin Mesbah <dev@aminmesbah.com>
Date: Fri, 26 Oct 2018 20:46:25 -0700
Make a stretchy buf
Diffstat:
M | calc.c | | | 57 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/calc.c b/calc.c
@@ -1,6 +1,61 @@
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
+
+struct BufHdr {
+ size_t cap;
+ size_t len;
+ uint8_t buf[];
+};
+
+#define buf__hdr(b) ((struct BufHdr *)((uint8_t *)(b) - offsetof(struct BufHdr, buf)))
+#define buf_cap(b) ((b) ? buf__hdr(b)->cap : 0)
+#define buf_len(b) ((b) ? buf__hdr(b)->len : 0)
+
+#define buf__must_grow(b, n) (buf_len(b) + (n) >= buf_cap(b))
+#define buf__maybe_grow(b, n) (buf__must_grow((b), (n)) ? (b) = buf__grow((b), buf_len(b) + (n), sizeof(*(b))) : 0)
+#define buf_push(b, x) (buf__maybe_grow((b), 1), (b)[buf__hdr(b)->len++] = (x))
+
+#define MAX(x, y) ((x) >= (y) ? (x) : (y))
+
+void *buf__grow(void *buf, size_t new_length, size_t element_size)
+{
+ size_t new_cap = MAX(1 + (2 * buf_cap(buf)), new_length);
+ assert(new_cap >= new_length);
+ size_t new_size = offsetof(struct BufHdr, buf) + (new_cap * element_size);
+ struct BufHdr *new_hdr = NULL;
+ if (buf)
+ {
+ new_hdr = realloc(buf__hdr(buf), new_size);
+ }
+ else
+ {
+ new_hdr = malloc(new_size);
+ new_hdr->len = 0;
+ }
+ new_hdr->cap = new_cap;
+ return new_hdr->buf;
+}
+
+void buf_test(void)
+{
+ int *buf = NULL;
+ assert(buf_len(buf) == 0);
+ for (size_t i = 0; i < 1000; ++i)
+ {
+ buf_push(buf, i);
+ }
+ assert(buf_len(buf) == 1000);
+ for (size_t i = 0; i < buf_len(buf); ++i)
+ {
+ printf("%d, ", buf[i]);
+ }
+ printf("\n");
+}
int main(void)
{
- printf("Hello, world");
+ buf_test();
}