summaryrefslogtreecommitdiff
path: root/core/ptrbox.c
diff options
context:
space:
mode:
authorChloe M. <chloe@aptel.org>2026-08-23 05:40:51 +0000
committerChloe M. <chloe@aptel.org>2026-08-23 05:40:51 +0000
commit6153bf6edb45e4ad1759e3db69e3a7358ae28b4e (patch)
treec6cad42382502e7f3a9cc840b6df12480d07f1ef /core/ptrbox.c
parent78b925a4d86b57e58e6322b7cad7bc47098618fd (diff)
core: Add support for pointer boxes
Pointer boxes are a way to manage memory and have all references released after operation, this way they do not need to be manually managed. Signed-off-by: Chloe M. <chloe@aptel.org>
Diffstat (limited to 'core/ptrbox.c')
-rw-r--r--core/ptrbox.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/core/ptrbox.c b/core/ptrbox.c
new file mode 100644
index 0000000..f6e2254
--- /dev/null
+++ b/core/ptrbox.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2026, Apollo Telephone Laboratories.
+ * Provided under the BSD-3 clause.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "defconf/ptrbox.h"
+
+static inline void
+ptrbox_insert(struct ptrbox *ptrbox, struct ptrbox_entry *entry)
+{
+ if (ptrbox == NULL || entry == NULL) {
+ return;
+ }
+
+ TAILQ_INSERT_TAIL(&ptrbox->entries, entry, link);
+ ++ptrbox->entry_count;
+}
+
+/*
+ * Allocate a new pointer box entry
+ *
+ * @data: Data to be associated with pointer box entry
+ */
+static struct ptrbox_entry *
+ptrbox_alloc_entry(void *data)
+{
+ struct ptrbox_entry *entry;
+
+ if (data == NULL) {
+ return NULL;
+ }
+
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL) {
+ return NULL;
+ }
+
+ entry->data = data;
+ return entry;
+}
+
+char *
+ptrbox_strdup(struct ptrbox *ptrbox, const char *s)
+{
+ struct ptrbox_entry *entry;
+ char *dup;
+
+ if (ptrbox == NULL || s == NULL) {
+ return NULL;
+ }
+
+ if ((dup = strdup(s)) == NULL) {
+ return NULL;
+ }
+
+ if ((entry = ptrbox_alloc_entry(dup)) == NULL) {
+ free(dup);
+ return NULL;
+ }
+
+ ptrbox_insert(ptrbox, entry);
+ return dup;
+}
+
+int
+ptrbox_init(struct ptrbox *ptrbox)
+{
+ if (ptrbox == NULL) {
+ return -1;
+ }
+
+ TAILQ_INIT(&ptrbox->entries);
+ ptrbox->entry_count = 0;
+ return 0;
+}
+
+void
+ptrbox_destroy(struct ptrbox *ptrbox)
+{
+ struct ptrbox_entry *entry, *tmp;
+
+ if (ptrbox == NULL) {
+ return;
+ }
+
+ entry = TAILQ_FIRST(&ptrbox->entries);
+ while (entry != NULL) {
+ if (entry->data != NULL) {
+ free(entry->data);
+ }
+
+ tmp = entry;
+ entry = TAILQ_NEXT(entry, link);
+ free(tmp);
+ }
+}