commit 3ad2986ed2a48ccb1443c60ac59d047c898f7943
parent ad04ace5ca3a8f90ef82a460341865c22a4d2f1b
Author: finwo <finwo@pm.me>
Date: Wed, 15 Jul 2026 02:27:56 +0200
Templated buffer implementation
Diffstat:
13 files changed, 186 insertions(+), 95 deletions(-)
diff --git a/.dep b/.dep
@@ -0,0 +1,2 @@
+cozis/tinytemplate https://git.finwo.net/misc/dep-repository/archives/heads/pkg/cozis/tinytemplate.tar.gz
+graphitemaster/incbin https://git.finwo.net/misc/dep-repository/archives/heads/pkg/graphitemaster/incbin.tar.gz
diff --git a/.gitignore b/.gitignore
@@ -1,3 +1,6 @@
/confgen
*.o
/lib/
+
+/src/util/buffer.c
+/src/util/buffer.h
diff --git a/Makefile b/Makefile
@@ -2,14 +2,17 @@
# LIBS=
SRC:=
SRC+=$(wildcard src/*.c)
-SRC+=$(wildcard src/*/*.c)
+SRC+=$(filter-out src/util/buffer.c, $(wildcard src/*/*.c))
+
+# Generated
+SRC+=src/util/buffer.c
CFLAGS?=-Wall -s -O2
INCLUDES:=
INCLUDES+=-I src
-# include lib/.dep/config.mk
+include lib/.dep/config.mk
CFLAGS+=$(INCLUDES)
@@ -22,6 +25,15 @@ BIN=confgen
default: $(BIN)
# default: $(BIN) $(BIN).1
+lib/cozis/tinytemplate/tt:
+ $(MAKE) --directory lib/cozis/tinytemplate
+
+src/util/buffer.h: template/util/buffer.h lib/cozis/tinytemplate/tt template/util/buffer.json
+ cat $< | lib/cozis/tinytemplate/tt template/util/buffer.json > $@
+
+src/util/buffer.c: template/util/buffer.c lib/cozis/tinytemplate/tt src/util/buffer.h template/util/buffer.json
+ cat $< | lib/cozis/tinytemplate/tt template/util/buffer.json > $@
+
%.o: %.c $(LIBS)
$(CC) $(CFLAGS) $(@:.o=.c) -D__NAME=\"$(BIN)\" -c -o $@
diff --git a/.dep b/src/util/.gitkeep
diff --git a/src/util/buffer.c b/src/util/buffer.c
@@ -1,61 +0,0 @@
-#include <string.h>
-#include <stdlib.h>
-
-#include "buffer.h"
-
-#ifndef MAX
-#define MAX(a,b) ((a)>(b)?(a):(b))
-#endif
-
-#ifndef MIN
-#define MIN(a,b) ((a)<(b)?(a):(b))
-#endif
-
-
-void confgen_buffer_append(struct confgen_buffer *subject, const char *source, size_t length) {
- if (!subject) return;
-
- // Initial alloc if blank buffer
- if (!subject->alloc) {
- size_t l = MAX(32, length);
- subject->alloc = malloc(l);
- subject->dat = subject->alloc;
- subject->cap = l;
- subject->len = 0;
- goto confgen_buffer_append_copy; // Simply skips cap checks
- }
-
- // Eject consumed data if we need space
- if (
- (subject->dat != subject->alloc) &&
- ((subject->len + length) > subject->cap)
- ) {
- size_t diff = subject->dat - subject->alloc;
- memmove(subject->alloc, subject->dat, subject->len);
- subject->cap += diff;
- subject->dat = subject->alloc;
- }
-
- // Grow buffer if still not enough space
- if ((subject->len + length) > subject->cap) {
- subject->cap = MAX(32, subject->cap * 2);
- subject->alloc = realloc(subject->alloc, subject->cap);
- subject->dat = subject->alloc;
- }
-
- // Add the data to the end
-confgen_buffer_append_copy:
- memcpy(subject->dat + subject->len, source, length);
- subject->len += length;
-}
-
-size_t confgen_buffer_consume(struct confgen_buffer *subject, size_t length) {
- if (!subject) return 0;
-
- size_t n = MIN(length, subject->len);
- subject->dat += n;
- subject->len -= n;
- subject->cap -= n;
-
- return n;
-}
diff --git a/src/util/buffer.h b/src/util/buffer.h
@@ -1,32 +0,0 @@
-#ifndef __CONFGEN_UTIL_BUFFER_H__
-#define __CONFGEN_UTIL_BUFFER_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>
-
-struct confgen_buffer {
- char *alloc;
- char *dat;
- size_t len;
- size_t cap;
-};
-
-/**
- * Append <length> bytes to the data in the buffer
- * Copies the data, does not mutate the source
- */
-void confgen_buffer_append(struct confgen_buffer *subject, const char *source, size_t length);
-
-/**
- * Remove <length> bytes from the front of the buffer
- */
-size_t confgen_buffer_consume(struct confgen_buffer *subject, size_t length);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // __CONFGEN_UTIL_BUFFER_H__
diff --git a/template/util/buffer.c b/template/util/buffer.c
@@ -0,0 +1,60 @@
+#include <string.h>
+#include <stdlib.h>
+
+#include "buffer.h"
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+void {{buffer_prefix}}_append(struct {{buffer_prefix}} *subject, const char *source, size_t length) {
+ if (!subject) return;
+
+ // Initial alloc if blank buffer
+ if (!subject->alloc) {
+ size_t l = MAX(32, length);
+ subject->alloc = malloc(l);
+ subject->dat = subject->alloc;
+ subject->cap = l;
+ subject->len = 0;
+ goto lbl_{{buffer_prefix}}_append_copy; // Simply skips cap checks
+ }
+
+ // Eject consumed data if we need space
+ if (
+ (subject->dat != subject->alloc) &&
+ ((subject->len + length) > subject->cap)
+ ) {
+ size_t diff = subject->dat - subject->alloc;
+ memmove(subject->alloc, subject->dat, subject->len);
+ subject->cap += diff;
+ subject->dat = subject->alloc;
+ }
+
+ // Grow buffer if still not enough space
+ if ((subject->len + length) > subject->cap) {
+ subject->cap = MAX(32, subject->cap * 2);
+ subject->alloc = realloc(subject->alloc, subject->cap);
+ subject->dat = subject->alloc;
+ }
+
+ // Add the data to the end
+lbl_{{buffer_prefix}}_append_copy:
+ memcpy(subject->dat + subject->len, source, length);
+ subject->len += length;
+}
+
+size_t {{buffer_prefix}}_consume(struct {{buffer_prefix}} *subject, size_t length) {
+ if (!subject) return 0;
+
+ size_t n = MIN(length, subject->len);
+ subject->dat += n;
+ subject->len -= n;
+ subject->cap -= n;
+
+ return n;
+}
diff --git a/template/util/buffer.h b/template/util/buffer.h
@@ -0,0 +1,32 @@
+#ifndef __Loh3Ain3_{{BUFFER_PREFIX}}_H__
+#define __Loh3Ain3_{{BUFFER_PREFIX}}_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+struct {{buffer_prefix}} {
+ char *alloc;
+ char *dat;
+ size_t len;
+ size_t cap;
+};
+
+/**
+ * Append <length> bytes to the data in the buffer
+ * Copies the data, does not mutate the source
+ */
+void {{buffer_prefix}}_append(struct {{buffer_prefix}} *subject, const char *source, size_t length);
+
+/**
+ * Remove <length> bytes from the front of the buffer
+ */
+size_t {{buffer_prefix}}_consume(struct {{buffer_prefix}} *subject, size_t length);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // __Loh3Ain3_{{BUFFER_PREFIX}}_H__
diff --git a/template/util/buffer.json b/template/util/buffer.json
@@ -0,0 +1,4 @@
+{
+ "buffer_prefix": "confgen_buffer",
+ "BUFFER_PREFIX": "CONFGEN_BUFFER"
+}
diff --git a/test/0000/confgen.hcl b/test/0000/confgen.hcl
@@ -1,5 +1,14 @@
name = "confgen_config"
+buffer_prefix = "blablabla" # <-- default to .name
+buffer_shared = false # <-- includes buffer implementation in single .h file
+
+
+buffer_shared = true
+buffer_shared_header = "util/buffer.h" # <-- Makes program output shared header here
+buffer_shared_code = "util/buffer.c" # <-- Makes program output shared buffer impl here
+buffer_prefix = "confgen_buffer_"
+
argument "name" {
type = "string"
}
diff --git a/test/0001/confgen.hcl b/test/0001/confgen.hcl
@@ -0,0 +1,16 @@
+name = "pmlag_conf"
+
+# This would generate the following C .h file, and accompanying .c file
+#
+# struct pmlag_conf_state {
+# struct confgen_buffer *input;
+# };
+#
+# struct pmlag_conf {
+# char *name;
+# };
+#
+#
+# struct pmlag_conf_state * pmlag_conf_start(); # <-- alloc buffer, etc
+# void pmlag_conf_update(struct pmlag_conf_state *state, const char *src, size_t len);
+# struct pmlag_conf * pmlag_conf_digest(struct pmlag_conf_state *state);
diff --git a/test/0002/confgen.hcl b/test/0002/confgen.hcl
@@ -0,0 +1,31 @@
+output_headers = "keepalived/src/config/config.h"
+output_parser = "keepalived/src/config/config.c"
+
+argument "daemonize" {
+ type = "boolean"
+}
+
+block "vrrp_instance" {
+ label = "name"
+ repeatable = true
+
+ argument "router_id" {
+ type = "integer"
+ }
+
+ block "auth" {
+ repeatable = false
+
+ argument "type" {
+ type = "string"
+ default = "PASS"
+ enum = [
+ "PASS"
+ "SOMETHING"
+ ]
+ }
+
+ }
+
+
+}
diff --git a/test/0002/keepalived.hcl b/test/0002/keepalived.hcl
@@ -0,0 +1,15 @@
+daemonize = false
+
+vrrp_instance "VRRP_1" {
+ router_id = 123
+
+ address "192.168.1.2/24" {
+ ...
+ }
+
+ auth {
+ type = "PASS"
+ password = "supers3cret"
+ }
+
+}