summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/ptrbox.c132
-rw-r--r--core/state.c6
-rw-r--r--include/cescal/ptrbox.h71
-rw-r--r--include/cescal/state.h3
4 files changed, 212 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);
+ }
+}
diff --git a/core/state.c b/core/state.c
index dce1316..6002957 100644
--- a/core/state.c
+++ b/core/state.c
@@ -33,6 +33,11 @@ state_init(struct cescal_state *state, const char *pathname)
return -1;
}
+ if (ptrbox_init(&state->ptrbox) < 0) {
+ close(state->in_fd);
+ return -1;
+ }
+
return 0;
}
@@ -41,4 +46,5 @@ state_close(struct cescal_state *state)
{
close(state->in_fd);
state->in_fd = -1;
+ ptrbox_destroy(&state->ptrbox);
}
diff --git a/include/cescal/ptrbox.h b/include/cescal/ptrbox.h
new file mode 100644
index 0000000..bde75f1
--- /dev/null
+++ b/include/cescal/ptrbox.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2026, Chloe M.
+ * Provided under the BSD-3 clause
+ */
+
+#ifndef CESCAL_PTRBOX_H
+#define CESCAL_PTRBOX_H 1
+
+/*
+ * Represents a pointer box entry in which allocated data can
+ * be stored within
+ *
+ * @data: Allocated data backed by entry
+ * @next: Next pointer box entry
+ */
+struct ptrbox_entry {
+ void *data;
+ struct ptrbox_entry *next;
+};
+
+/*
+ * Represents a pointer box that enables RAII like behavior
+ *
+ * @head: Pointer box head
+ * @tail: Pointer box tail
+ */
+struct ptrbox {
+ struct ptrbox_entry *head;
+ struct ptrbox_entry *tail;
+};
+
+/*
+ * Initialize a pointer box
+ *
+ * @ptrbox: Pointer box to initialize
+ *
+ * Returns zero on success
+ */
+int ptrbox_init(struct ptrbox *ptrbox);
+
+/*
+ * Allocate memory and save the reference within a pointer box
+ *
+ * @ptrbox: Pointer box to save reference within
+ * @len: Length of memory to allocate
+ *
+ * Returns the base of the allocated memory on success, otherwise
+ * NULL.
+ */
+void *ptrbox_alloc(struct ptrbox *ptrbox, size_t len);
+
+/*
+ * Duplicate a string and store the reference within a
+ * pointer box
+ *
+ * @ptrbox: Pointer box to store reference within
+ * @s: String to duplicate
+ *
+ * Returns the duplicated string on success, otherwise NULL.
+ */
+char *ptrbox_strdup(struct ptrbox *ptrbox, const char *s);
+
+/*
+ * Destroy a pointer box along with all references stored
+ * within
+ *
+ * @ptrbox: Pointer box to destroy
+ */
+void ptrbox_destroy(struct ptrbox *ptrbox);
+
+#endif /* !CESCAL_PTRBOX_H */
diff --git a/include/cescal/state.h b/include/cescal/state.h
index e832bc9..566b5a2 100644
--- a/include/cescal/state.h
+++ b/include/cescal/state.h
@@ -9,6 +9,7 @@
#include <stdint.h>
#include "cescal/readbuf.h"
#include "cescal/tokbuf.h"
+#include "cescal/ptrbox.h"
/*
* Compiler state machine
@@ -16,11 +17,13 @@
* @in_fd: Input file descriptor
* @rb: Read buffer
* @tokbuf: Token buffer
+ * @ptrbox: Global pointer box
*/
struct cescal_state {
int in_fd;
struct readbuf rb;
struct tokbuf tokbuf;
+ struct ptrbox ptrbox;
};
/*