commit 2136405a306d2f9eb5f13a782d3b81a2faa98d8d
parent 37b67bc94dd6bdd14bd5fa86c3d308ad69402d86
Author: finwo <finwo@pm.me>
Date: Sun, 15 Mar 2026 02:21:14 +0100
Replace manual templating by existing library
Diffstat:
2 files changed, 80 insertions(+), 17 deletions(-)
diff --git a/Makefile b/Makefile
@@ -22,6 +22,9 @@ LIBS:=
LIBS+=lib/cofyc/argparse
SRC+=lib/cofyc/argparse/argparse.c
+LIBS+=lib/cozis/tinytemplate
+SRC+=lib/cozis/tinytemplate/src/tinytemplate.c
+
LIBS+=lib/emmanuel-marty/em_inflate
SRC+=lib/emmanuel-marty/em_inflate/lib/em_inflate.c
@@ -53,6 +56,12 @@ lib/cofyc/argparse:
mkdir -p lib/.dep/include/cofyc
ln -s ../../../cofyc/argparse/argparse.h lib/.dep/include/cofyc/argparse.h
+lib/cozis/tinytemplate:
+ mkdir -p lib/cozis/tinytemplate
+ curl -sL https://github.com/cozis/tinytemplate/archive/refs/heads/main.tar.gz | tar xzv --strip-components=1 -C lib/cozis/tinytemplate
+ mkdir -p lib/.dep/include/cozis
+ ln -s ../../../cozis/tinytemplate/src/tinytemplate.h lib/.dep/include/cozis/tinytemplate.h
+
lib/emmanuel-marty/em_inflate:
mkdir -p lib/emmanuel-marty/em_inflate
curl -sL https://github.com/emmanuel-marty/em_inflate/archive/refs/heads/master.tar.gz | tar xzv --strip-components=1 -C lib/emmanuel-marty/em_inflate
diff --git a/src/command/install/main.c b/src/command/install/main.c
@@ -15,6 +15,7 @@
#include "command/command.h"
#include "common/github-utils.h"
#include "common/net-utils.h"
+#include "cozis/tinytemplate.h"
#include "emmanuel-marty/em_inflate.h"
#include "erkkah/naett.h"
#include "rxi/microtar.h"
@@ -402,25 +403,78 @@ static int install_dependency(const char *name, const char *spec) {
if (dst_config) {
char line[LINE_MAX];
while (fgets(line, sizeof(line), dep_config)) {
- // Replace __DIRNAME and {__DIRNAME__} with the dependency's path (lib_path)
- char modified[LINE_MAX * 2]; // enough space for replacements
- char *src = line;
- char *dst = modified;
- while (*src) {
- if (strncmp(src, "__DIRNAME", 9) == 0) {
- strcpy(dst, lib_path);
- dst += strlen(lib_path);
- src += 9;
- } else if (strncmp(src, "{{module.dirname}}", 18) == 0) {
- strcpy(dst, lib_path);
- dst += strlen(lib_path);
- src += 18;
- } else {
- *dst++ = *src++;
+ size_t linelen = strlen(line);
+ if (linelen > 0 && line[linelen - 1] == '\n') {
+ line[--linelen] = '\0';
+ }
+ if (linelen > 0 && line[linelen - 1] == '\r') {
+ line[--linelen] = '\0';
+ }
+
+ tinytemplate_instr_t program[256];
+ size_t num_instr = 0;
+ char errmsg[256];
+
+ if (linelen == 0) {
+ fputc('\n', dst_config);
+ continue;
+ }
+
+ if (tinytemplate_compile(line, linelen, program, 256, &num_instr, errmsg, sizeof(errmsg)) !=
+ TINYTEMPLATE_STATUS_DONE) {
+ fprintf(stderr, "Warning: template compile failed: %s\n", errmsg);
+ fputs(line, dst_config);
+ fputc('\n', dst_config);
+ continue;
+ }
+
+ struct {
+ const char *lib_path;
+ FILE *fp;
+ } ctx = {lib_path, dst_config};
+
+ bool module_dict_getter(void *data, const char *name, size_t len, tinytemplate_value_t *value) {
+ if (len == 7 && strncmp(name, "dirname", 7) == 0) {
+ const char *lib_path = data;
+ tinytemplate_set_string(value, lib_path, strlen(lib_path));
+ return true;
}
+ char orig[256];
+ int n = snprintf(orig, sizeof(orig), "{%.*s}", (int)len, name);
+ tinytemplate_set_string(value, orig, n);
+ return true;
+ }
+
+ bool template_getter(void *data, const char *name, size_t len, tinytemplate_value_t *value) {
+ struct {
+ const char *lib_path;
+ FILE *fp;
+ } *ctx = data;
+
+ if (len == 6 && strncmp(name, "module", 6) == 0) {
+ tinytemplate_set_dict(value, (void *)ctx->lib_path, module_dict_getter);
+ return true;
+ }
+
+ char orig[256];
+ int n = snprintf(orig, sizeof(orig), "{{%.*s}}", (int)len, name);
+ tinytemplate_set_string(value, orig, n);
+ return true;
+ }
+
+ void template_callback(void *data, const char *str, size_t len) {
+ struct {
+ const char *lib_path;
+ FILE *fp;
+ } *ctx = data;
+ fwrite(str, 1, len, ctx->fp);
+ }
+
+ if (tinytemplate_eval(line, program, &ctx, template_getter, template_callback, errmsg, sizeof(errmsg)) !=
+ TINYTEMPLATE_STATUS_DONE) {
+ fprintf(stderr, "Warning: template eval failed: %s\n", errmsg);
}
- *dst = '\0';
- fputs(modified, dst_config);
+ fputc('\n', dst_config);
}
// Ensure a newline at end of appended content if not already ending with newline
// (optional, but we can add a newline to separate entries)