diff options
Diffstat (limited to 'lib/cbit')
-rw-r--r-- | lib/cbit/cqueue.c | 23 | ||||
-rw-r--r-- | lib/cbit/cqueue.h | 60 | ||||
-rw-r--r-- | lib/cbit/htab.h | 3 | ||||
-rw-r--r-- | lib/cbit/vec.c | 2 | ||||
-rw-r--r-- | lib/cbit/vec.h | 2 |
5 files changed, 87 insertions, 3 deletions
diff --git a/lib/cbit/cqueue.c b/lib/cbit/cqueue.c new file mode 100644 index 0000000..aebc265 --- /dev/null +++ b/lib/cbit/cqueue.c @@ -0,0 +1,23 @@ +#include "circle.h" + +void cqueue_realloc_internal(struct cqueue_internal *ci, + size_t new_capacity_bytes) { + char *storage = (char *) malloc(new_capacity_bytes); + char *new_write_ptr; + if (c->write_ptr >= c->read_ptr) { + size_t diff = c->write_ptr - c->read_ptr; + memcpy(storage, c->read_ptr, diff); + new_write_ptr = storage + diff; + } else { + size_t diff1 = c->end - c->read_ptr; + size_t diff2 = c->write_ptr - c->start; + memcpy(storage, c->read_ptr, diff1); + char *tmp = storage + diff1; + memcpy(tmp, c->start, diff2); + new_write_ptr = tmp + diff2; + } + c->start = storage; + c->end = storage + new_capacity_bytes; + c->read_ptr = storage; + c->write_ptr = new_write_ptr; +} diff --git a/lib/cbit/cqueue.h b/lib/cbit/cqueue.h new file mode 100644 index 0000000..0ab5488 --- /dev/null +++ b/lib/cbit/cqueue.h @@ -0,0 +1,60 @@ +#pragma once +#include "misc.h" + +struct cqueue_internal { + char *start, *end, *read_ptr, *write_ptr; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +void cqueue_realloc_internal(struct cqueue_internal *ci, + size_t new_capacity_bytes); +#ifdef __cplusplus +} +#endif + +#define DECL_CQUEUE(ty, name) \ + typedef ty __CQUEUE_TY_##name; \ + struct cqueue_##name { \ + union { \ + struct cqueue_internal ci; \ + struct { \ + __CQUEUE_TY_##name *start, *end, *read_ptr, *write_ptr; \ + }; \ + }; \ + }; \ + UNUSED_STATIC_INLINE \ + void cqueue_free_storage_##name(struct cqueue_##name *c) { \ + free(c->start); \ + } \ + UNUSED_STATIC_INLINE \ + void cqueue_realloc_##name(struct cqueue_##name *c, size_t new_capacity) { \ + cqueue_realloc_internal(&c->ci, safe_mul(new_capacity, \ + sizeof(__CQUEUE_TY_##name))); \ + } \ + UNUSED_STATIC_INLINE \ + __CQUEUE_TY_##name *cqueue_appendp_##name(struct cqueue_##name *c) { \ + if (c->write_ptr + 1 == c->read_ptr) \ + cqueue_realloc_##name(c, (c->end - c->start) * 2 + 3); \ + __CQUEUE_TY_##name *ret = c->write_ptr++; \ + if (c->write_ptr == c->end) \ + c->write_ptr = c->start; \ + return ret; \ + } \ + UNUSED_STATIC_INLINE \ + __CQUEUE_TY_##name *cqueue_shiftp_##name(struct cqueue_##name *c) { \ + if (c->read_ptr == c->write_ptr) \ + return NULL; \ + __CQUEUE_TY_##name *ret = c->read_ptr++; \ + if (c->read_ptr == c->end) \ + c->read_ptr = c->start; \ + return ret; \ + } \ + UNUSED_STATIC_INLINE \ + size_t cqueue_length_##name(const struct cqueue_name *c) { \ + return ((c->write_ptr - c->start) - (c->read_ptr - c->start)) \ + % (c->end - c->start); \ + } \ + typedef char __plz_end_decl_cqueue_with_semicolon_##name diff --git a/lib/cbit/htab.h b/lib/cbit/htab.h index 82e8117..1a5e71f 100644 --- a/lib/cbit/htab.h +++ b/lib/cbit/htab.h @@ -266,7 +266,8 @@ struct htab_internal { void htab_free_storage_##name(htab_ty *ht) { \ if (ht->base != ht->storage) \ free(ht->base); \ - } + } \ + typedef char __plz_end_decl_htab_with_semicolon_##name #define HTAB_STORAGE_CAPA(name, n) \ struct { \ diff --git a/lib/cbit/vec.c b/lib/cbit/vec.c index 2f875ff..8202ea9 100644 --- a/lib/cbit/vec.c +++ b/lib/cbit/vec.c @@ -1,4 +1,4 @@ -#include "cbit/vec.h" +#include "vec.h" #include <stdio.h> #include <stdlib.h> diff --git a/lib/cbit/vec.h b/lib/cbit/vec.h index 3e8b7e3..fe8df71 100644 --- a/lib/cbit/vec.h +++ b/lib/cbit/vec.h @@ -101,7 +101,7 @@ void vec_realloc_internal_as_necessary(struct vec_internal *vi, (orig - (idx + num)) * sizeof(v->els[0])); \ vec_resize_##name(v, orig - num); \ } \ - + typedef char __plz_end_decl_vec_with_semicolon_##name #define VEC_TY(name) __VEC_TY_##name |