From f99c1d678f3310a3679b24e518355fbb00211273 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sat, 23 May 2026 06:03:23 -0400 Subject: core: Add pointer box / RAII impl Signed-off-by: Ian Moffett --- core/ptrbox.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 core/ptrbox.c (limited to 'core/ptrbox.c') 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 +#include +#include +#include +#include +#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); + } +} -- cgit v1.2.3