From d3d11da1b4c050923930a6765c2cc9204ddc844c Mon Sep 17 00:00:00 2001
From: overflowerror <mail@overflowerror.com>
Date: Sun, 23 May 2021 16:31:33 +0200
Subject: [PATCH] added renderTemplateStr() function to interface

---
 src/templates.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++---
 src/templates.h |  3 ++
 2 files changed, 80 insertions(+), 4 deletions(-)

diff --git a/src/templates.c b/src/templates.c
index d9708ca..cf8d32e 100644
--- a/src/templates.c
+++ b/src/templates.c
@@ -11,7 +11,7 @@
 typedef void (*template_t)(FILE*, va_list);
 typedef size_t (*template_length_t)(va_list);
 
-struct {
+struct entry {
 	const char* name;
 	template_t f;
 	template_length_t s;
@@ -28,6 +28,16 @@ static template_t _findTemplate(const char* name) {
 	return NULL;
 }
 
+static template_length_t _findTemplateSize(const char* name) {
+	for (size_t i = 0; i < templateno; i++) {
+		if (strcmp(templates[i].name, name) == 0) {
+			return templates[i].s;
+		}
+	}
+	
+	return NULL;
+}
+
 void _registerTemplate(const char* name, template_t f, template_length_t s) {
 	if (templateno >= MAX_TEMPLATES) {
 		panic("max number of templates exceeded");
@@ -43,9 +53,9 @@ void _registerTemplate(const char* name, template_t f, template_length_t s) {
 	templates[templateno++].s = s;
 }
 
-static void emptyTemplate(FILE* out, va_list _) {
-	fprintf(out, "Template not found.\n");
-}
+
+static size_t emptyTemplateSize(va_list _) { return 0; }
+static void emptyTemplate(FILE* out, va_list _) { }
 
 void renderTemplate(const char* name, FILE* out, ...) {
 	template_t t = _findTemplate(name);
@@ -62,3 +72,66 @@ void renderTemplate(const char* name, FILE* out, ...) {
 	
 	va_end(argptr);
 }
+
+size_t sizeTemplate(const char* name, ...) {
+	template_length_t s = _findTemplateSize(name);
+	
+	if (s == NULL) {
+		fprintf(stderr, "warning: template '%s' does not exist.\n", name);
+		s = &emptyTemplateSize;
+	}
+	
+	size_t result;
+	
+	va_list argptr;
+	va_start(argptr, name);
+	
+	result = s(argptr);
+	
+	va_end(argptr);
+	
+	return result;
+}
+
+char* renderTemplateStr(const char* name, ...) {
+	template_t t = _findTemplate(name);
+	template_length_t s = _findTemplateSize(name);
+	
+	if (t == NULL) {
+		fprintf(stderr, "warning: template '%s' does not exist.\n", name);
+		t = &emptyTemplate;
+		s = &emptyTemplateSize;
+	}
+	
+	size_t length;
+	char* result;
+	
+	va_list argptr, argptr2;
+	va_start(argptr, name);
+	va_copy(argptr2, argptr);
+	
+	length = s(argptr);
+	
+	va_end(argptr);
+	
+	result = malloc(length + 1);
+	if (result == NULL) {
+		va_end(argptr2);
+		return NULL;
+	}
+	
+	FILE* out = fmemopen(result, length, "w");
+	if (out == NULL) {
+		va_end(argptr2);
+		return NULL;
+	}
+	
+	t(out, argptr2);
+	fclose(out);
+	
+	va_end(argptr2);
+	
+	result[length] = '\0';
+	
+	return result;
+}
diff --git a/src/templates.h b/src/templates.h
index feb3d90..a042264 100644
--- a/src/templates.h
+++ b/src/templates.h
@@ -2,7 +2,10 @@
 #define TEMPLATES_H_
 
 #include <stdio.h>
+#include <stdlib.h>
 
+size_t sizeTemplate(const char*, ...);
 void renderTemplate(const char*, FILE*, ...);
+char* renderTemplateStr(const char*, ...);
 
 #endif