diff --git a/ltm/src/_include/ltm/template_internal.h b/ltm/src/_include/ltm/template_internal.h index 2c750f8..cbac721 100644 --- a/ltm/src/_include/ltm/template_internal.h +++ b/ltm/src/_include/ltm/template_internal.h @@ -93,14 +93,20 @@ typedef struct ltm_instance_block { struct ltm_instance_block *next; } ltm_instance_block; +ltm_err ltm_instance_block_init(ltm_instance_block **out); + struct ltm_instance { + const ltm_template *template; struct { ltm_instance_block *head; ltm_instance_block *tail; ltm_instance_block *current; } blocks; + ltm_instance_block ***vars; // How many bytes of the current block have been written size_t written; }; +ltm_err ltm_instance_init(ltm_instance **out); + #endif diff --git a/ltm/src/ltm_instance.c b/ltm/src/ltm_instance.c new file mode 100644 index 0000000..6f9af67 --- /dev/null +++ b/ltm/src/ltm_instance.c @@ -0,0 +1,76 @@ +#include "ltm/template.h" +#include "ltm/template_internal.h" + +ltm_err ltm_instance_block_init(ltm_instance_block **out) { + ltm_instance_block *block = calloc(1, sizeof(ltm_instance_block)); + + if (block == NULL) { + return ltm_err_failed_alloc; + } + + *out = block; + + return ltm_err_ok; +} + +ltm_err ltm_instance_init(ltm_instance **out) { + ltm_instance *instance = calloc(1, sizeof(ltm_instance)); + + if (instance == NULL) { + return ltm_err_failed_alloc; + } + + *out = instance; + + return ltm_err_ok; +} + +ltm_err ltm_template_instantiate(ltm_instance **out, + const ltm_template *template) { + ltm_instance *instance; + LTM_RES(ltm_instance_init(&instance)); + + instance->template = template; + + ltm_instance_block ***vars = + malloc(template->names.len * sizeof(ltm_instance_block **)); + + if (vars == NULL) { + return ltm_err_failed_alloc; + } + + instance->vars = vars; + + for (size_t block_index = 0; block_index < template->blocks.len; + block_index++) { + ltm_template_block *template_block = &template->blocks.arr[block_index]; + + switch (template_block->type) { + case ltm_template_block_type_literal: { + ltm_instance_block *block; + LTM_RES(ltm_instance_block_init(&block)); + + block->type = ltm_instance_block_type_buf; + block->data.ptr = template_block->data.ptr; + block->data.len = template_block->data.len; + + if (instance->blocks.head == NULL) { + instance->blocks.head = block; + instance->blocks.tail = block; + instance->blocks.current = block; + } else { + instance->blocks.tail->next = block; + instance->blocks.tail = block; + } + } break; + case ltm_template_block_type_var: + case ltm_template_block_type_nested: + *vars = &instance->blocks.tail->next; + vars++; + } + } + + *out = instance; + + return ltm_err_ok; +}