From 4827dcf8e4a34df9322bcdf2c1c7055090d8d8fb Mon Sep 17 00:00:00 2001 From: Dan Cross Date: Tue, 9 Oct 2018 15:55:14 +0000 Subject: [PATCH] Add a pointer vector abstraction. There are lots of places where we want a growable vector of pointers. Add one. Signed-off-by: Dan Cross --- src/bbs.h | 15 +++++++++++ src/util.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/src/bbs.h b/src/bbs.h index 19657cc..6f26a44 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -260,6 +260,21 @@ struct blog_entry_t { time_t date; }; +struct ptr_vector { + size_t len; + size_t capacity; + void **ptrs; +}; + +extern void init_ptr_vector(struct ptr_vector *vec); +extern void ptr_vector_clear(struct ptr_vector *vec); +extern void *ptr_vector_get(struct ptr_vector *vec, size_t i); +extern int ptr_vector_put(struct ptr_vector *vec, void *p, size_t i); +extern void *ptr_vector_del(struct ptr_vector *vec, size_t i); +extern int ptr_vector_append(struct ptr_vector *vec, void *p); +extern size_t ptr_vector_len(struct ptr_vector *vec); +extern void destroy_ptr_vector(struct ptr_vector *vec); + extern char *str_replace(const char *orig, const char *rep, const char *with); extern int copy_file(char *src, char *dest); extern int recursive_delete(const char *dir); diff --git a/src/util.c b/src/util.c index 353d70b..f23e3d9 100644 --- a/src/util.c +++ b/src/util.c @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -86,3 +87,76 @@ char *str3dup(const char *a, const char *b, const char *c) { char *str2dup(const char *a, const char *b) { return str5dup(a, b, "", "", ""); } + +void init_ptr_vector(struct ptr_vector *vec) { + assert(vec != NULL); + memset(vec, 0, sizeof(*vec)); +} + +void ptr_vector_clear(struct ptr_vector *vec) { + assert(vec != NULL); + vec->len = 0; + memset(vec->ptrs, 0, sizeof(void *) * vec->capacity); +} + +void *ptr_vector_get(struct ptr_vector *vec, size_t i) { + assert(vec != NULL); + if (i >= vec->len) + return NULL; + assert(vec->ptrs != NULL); + return vec->ptrs[i]; +} + +int ptr_vector_put(struct ptr_vector *vec, void *p, size_t i) { + assert(vec != NULL); + if (i >= vec->len) + return 0; + assert(vec->ptrs != NULL); + vec->ptrs[i] = p; + return 1; +} + +void *ptr_vector_del(struct ptr_vector *vec, size_t i) { + void *p; + assert(vec != NULL); + if (i >= vec->len) + return NULL; + assert(vec->ptrs != NULL); + p = vec->ptrs[i]; + memmove(vec->ptrs + i, vec->ptrs + i + 1, + (vec->len - (i + 1)) * sizeof(void *)); + --vec->len; + return p; +} + +int ptr_vector_append(struct ptr_vector *vec, void *p) { + assert(vec != NULL); + if (vec->len == vec->capacity) { + void **ps; + size_t oldcap = vec->capacity; + if (vec->capacity == 0) + vec->capacity = 1; + else + vec->capacity *= 2; + ps = realloc(vec->ptrs, vec->capacity * sizeof(void *)); + assert(ps != NULL); + memset(vec->ptrs + oldcap, 0, (vec->capacity - oldcap) * sizeof(void *)); + vec->ptrs = ps; + } + vec->ptrs[vec->len] = p; + ++vec->len; + return 1; +} + +size_t ptr_vector_len(struct ptr_vector *vec) { + assert(vec != NULL); + return vec->len; +} + +void destroy_ptr_vector(struct ptr_vector *vec) { + assert(vec != NULL); + free(vec->ptrs); + vec->ptrs = NULL; + vec->capacity = 0; + vec->len = 0; +}