diff options
| author | Ian Moffett <ian@mirocom.org> | 2026-05-23 06:03:23 -0400 |
|---|---|---|
| committer | Ian Moffett <ian@mirocom.org> | 2026-05-23 06:04:40 -0400 |
| commit | f99c1d678f3310a3679b24e518355fbb00211273 (patch) | |
| tree | 8ec6498d4c591fd2776e203296232d73740200f3 /core/ptrbox.c | |
| parent | 32635789dca1c35224ce6e320a03db23e56d380f (diff) | |
core: Add pointer box / RAII impl
Signed-off-by: Ian Moffett <ian@mirocom.org>
Diffstat (limited to 'core/ptrbox.c')
| -rw-r--r-- | core/ptrbox.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/core/ptrbox.c b/core/ptrbox.c new file mode 100644 index 0000000..2bdaa9c --- /dev/null +++ b/core/ptrbox.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2026, Chloe M. + * Provided under the BSD-3 clause + */ + +#include <stddef.h> +#include <stdint.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include "cescal/ptrbox.h" + +/* + * Allocate a pointer box entry to be used + */ +static struct ptrbox_entry * +ptrbox_alloc_entry(void) +{ + struct ptrbox_entry *entry; + + if ((entry = malloc(sizeof(*entry))) == NULL) { + return NULL; + } + + entry->data = NULL; + entry->next = NULL; + return entry; +} + +static int +ptrbox_push_entry(struct ptrbox *ptrbox, struct ptrbox_entry *entry) +{ + if (ptrbox == NULL || entry == NULL) { + errno = EINVAL; + return -1; + } + + if (ptrbox->head == NULL || ptrbox->tail == NULL) { + ptrbox->head = entry; + ptrbox->tail = entry; + } else { + ptrbox->head->next = entry; + ptrbox->head = entry; + } + + return 0; +} + +int +ptrbox_init(struct ptrbox *ptrbox) +{ + if (ptrbox == NULL) { + errno = EINVAL; + return -1; + } + + ptrbox->head = NULL; + ptrbox->tail = NULL; + return 0; +} + +void * +ptrbox_alloc(struct ptrbox *ptrbox, size_t len) +{ + struct ptrbox_entry *entry; + void *p; + + if (ptrbox == NULL || len == 0) { + errno = EINVAL; + return NULL; + } + + if ((p = malloc(len)) == NULL) { + return NULL; + } + + if ((entry = ptrbox_alloc_entry()) == NULL) { + free(p); + return NULL; + } + + entry->data = p; + if (ptrbox_push_entry(ptrbox, entry) < 0) { + free(p); + free(entry); + return NULL; + } + + return 0; +} + +char * +ptrbox_strdup(struct ptrbox *ptrbox, const char *s) +{ + char *sdup; + size_t slen; + + if (ptrbox == NULL || s == NULL) { + errno = EINVAL; + return NULL; + } + + slen = strlen(s) + 1; + if ((sdup = ptrbox_alloc(ptrbox, slen)) == NULL) { + return NULL; + } + + memcpy(sdup, s, slen); + return sdup; +} + +void +ptrbox_destroy(struct ptrbox *ptrbox) +{ + struct ptrbox_entry *entry, *tmp; + + if (ptrbox == NULL) { + return; + } + + if ((entry = ptrbox->tail) == NULL) { + return; + } + + while (entry != NULL) { + tmp = entry; + entry = entry->next; + + free(tmp->data); + free(tmp); + } +} |
