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 +#include +size_t sizeTemplate(const char*, ...); void renderTemplate(const char*, FILE*, ...); +char* renderTemplateStr(const char*, ...); #endif