summaryrefslogtreecommitdiff
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
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>
-rw-r--r--core/lexer.c4
-rw-r--r--core/ptrbox.c98
-rw-r--r--core/state.c9
-rw-r--r--head/defconf/ptrbox.h58
-rw-r--r--head/defconf/state.h3
5 files changed, 170 insertions, 2 deletions
diff --git a/core/lexer.c b/core/lexer.c
index 2eb50a1..e93c629 100644
--- a/core/lexer.c
+++ b/core/lexer.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include "defconf/lexer.h"
+#include "defconf/ptrbox.h"
/* Constants */
#define MAX_KW_LEN 32
@@ -109,7 +110,7 @@ lexer_scan_ident(struct defconf_state *state, int lc)
if (!isalnum(c) && c != '_') {
lexer_putback(state, c);
buf[bufind] = '\0';
- return strdup(buf);
+ return ptrbox_strdup(&state->ptrbox, buf);
}
buf[bufind++] = c;
@@ -177,7 +178,6 @@ lexer_scan(struct defconf_state *state, struct token *result)
/* Scan for an identifier */
if ((ident = lexer_scan_ident(state, c)) != NULL) {
if (lexer_check_kw(ident, result) == 0) {
- free(ident);
return 0;
}
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);
+ }
+}
diff --git a/core/state.c b/core/state.c
index ce1c286..c55a5be 100644
--- a/core/state.c
+++ b/core/state.c
@@ -9,6 +9,8 @@
int
defconf_state_init(const char *in_path, struct defconf_state *state)
{
+ int error;
+
if (in_path == NULL || state == NULL) {
return -1;
}
@@ -19,6 +21,12 @@ defconf_state_init(const char *in_path, struct defconf_state *state)
return -1;
}
+ if ((error = ptrbox_init(&state->ptrbox)) < 0) {
+ fclose(state->in_fp);
+ printf("fatal: failed to create pointer box\n");
+ return error;
+ }
+
state->lex_cache = '\0';
return 0;
}
@@ -32,4 +40,5 @@ defconf_state_destroy(struct defconf_state *state)
fclose(state->in_fp);
state->in_fp = NULL;
+ ptrbox_destroy(&state->ptrbox);
}
diff --git a/head/defconf/ptrbox.h b/head/defconf/ptrbox.h
new file mode 100644
index 0000000..3358595
--- /dev/null
+++ b/head/defconf/ptrbox.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2026, Apollo Telephone Laboratories.
+ * Provided under the BSD-3 clause.
+ */
+
+#ifndef DEFCONF_PTRBOX_H
+#define DEFCONF_PTRBOX_H 1
+
+#include <sys/queue.h>
+#include <stdint.h>
+#include <stddef.h>
+
+/*
+ * Represents a pointer box entry
+ *
+ * @data: Allocated data
+ * @link: TAILQ link
+ */
+struct ptrbox_entry {
+ void *data;
+ TAILQ_ENTRY(ptrbox_entry) link;
+};
+
+/*
+ * A pointer box stores references to memory to be freed later on
+ *
+ * @entries: Entries within pointer box
+ * @entry_count: Number of pointer box entries
+ */
+struct ptrbox {
+ TAILQ_HEAD(, ptrbox_entry) entries;
+ size_t entry_count;
+};
+
+/*
+ * Wrapper over strdup() but saved in a pointer box
+ *
+ * @ptrbox: Pointer box to allocate into
+ * @s: String to dup
+ *
+ * Returns the base of the dup'd string on success, otherwise
+ * NULL on failure.
+ */
+char *ptrbox_strdup(struct ptrbox *ptrbox, const char *s);
+
+/*
+ * Initialize a pointer box
+ */
+int ptrbox_init(struct ptrbox *ptrbox);
+
+/*
+ * Destroy a pointer box and all of its entries
+ *
+ * @ptrbox: Pointer box to destroy
+ */
+void ptrbox_destroy(struct ptrbox *ptrbox);
+
+#endif /* !DEFCONF_PTRBOX_H */
diff --git a/head/defconf/state.h b/head/defconf/state.h
index 524af3b..aa99105 100644
--- a/head/defconf/state.h
+++ b/head/defconf/state.h
@@ -9,16 +9,19 @@
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
+#include "defconf/ptrbox.h"
/*
* DEFCONF state machine
*
* @in_fp: Input file pointer
* @lex_cache: Putback cache
+ * @ptrbox: Global pointer box
*/
struct defconf_state {
FILE *in_fp;
int lex_cache;
+ struct ptrbox ptrbox;
};
/*