diff options
| author | Chloe M. <chloe@aptel.org> | 2026-08-23 05:40:51 +0000 |
|---|---|---|
| committer | Chloe M. <chloe@aptel.org> | 2026-08-23 05:40:51 +0000 |
| commit | 6153bf6edb45e4ad1759e3db69e3a7358ae28b4e (patch) | |
| tree | c6cad42382502e7f3a9cc840b6df12480d07f1ef | |
| parent | 78b925a4d86b57e58e6322b7cad7bc47098618fd (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.c | 4 | ||||
| -rw-r--r-- | core/ptrbox.c | 98 | ||||
| -rw-r--r-- | core/state.c | 9 | ||||
| -rw-r--r-- | head/defconf/ptrbox.h | 58 | ||||
| -rw-r--r-- | head/defconf/state.h | 3 |
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; }; /* |
