diff --git a/ltm/include/ltm/common.h b/ltm/include/ltm/common.h index 6851359..ef86779 100644 --- a/ltm/include/ltm/common.h +++ b/ltm/include/ltm/common.h @@ -17,16 +17,10 @@ } \ } -#define LTM_MIN(x, y) ((x) < (y) ? (x) : (y)) -#define LTM_MAX(x, y) ((x) > (y) ? (x) : (y)) - typedef enum ltm_err { ltm_err_ok = 0, ltm_err_invalid_template, ltm_err_failed_alloc, - ltm_err_not_found, - ltm_err_wrong_block_type, - ltm_err_done, } ltm_err; #endif diff --git a/ltm/include/ltm/template.h b/ltm/include/ltm/template.h index ed802f1..445fbf9 100644 --- a/ltm/include/ltm/template.h +++ b/ltm/include/ltm/template.h @@ -28,12 +28,6 @@ ltm_err ltm_template_compile(ltm_template **out, const char *template); ltm_err ltm_template_compile_n(ltm_template **out, const char *template, size_t len); -/** - * Free the template instance. After freeing a template, no instances associated - * with it are safe to use. - */ -void ltm_template_free(ltm_template *template); - /** * Represents a specific instance of a template. */ @@ -45,15 +39,8 @@ typedef struct ltm_instance ltm_instance; ltm_err ltm_template_instantiate(ltm_instance **out, const ltm_template *template); -/** - * Free the given instance, as well as all nested instances. - */ -void ltm_instance_free(ltm_instance *instance); - typedef enum ltm_instance_block_type { ltm_instance_block_type_buf = 0, - ltm_instance_block_type_buf_owned, - ltm_instance_block_type_nested, } ltm_instance_block_type; /** @@ -70,23 +57,4 @@ ltm_err ltm_instance_block_add_var(ltm_instance *instance, const char *name, ltm_err ltm_instance_block_add_nested(ltm_instance **out, ltm_instance *instance, const char *name); -/** - * Calculate the size of the resulting output of this instance. - */ -size_t ltm_instance_size(const ltm_instance *instance); - -/** - * Write at most `len` bytes to the given buffer. - * - * @param written outputs how many bytes were written to `buf` - * @param buf buffer to write to - * @param len length of the buffer - * @param instance instance to write - * @return `ltm_err_ok` if write was successful but there's more to be written, - * `ltm_err_done` if everything has been written successfully, or some other - * error code - */ -ltm_err ltm_instance_write(size_t *written, char *buf, size_t len, - ltm_instance *instance); - #endif diff --git a/ltm/src/ltm_instance.c b/ltm/src/ltm_instance.c index 0db85c2..6f9af67 100644 --- a/ltm/src/ltm_instance.c +++ b/ltm/src/ltm_instance.c @@ -1,7 +1,3 @@ -#include -#include - -#include "ltm/common.h" #include "ltm/template.h" #include "ltm/template_internal.h" @@ -29,32 +25,6 @@ ltm_err ltm_instance_init(ltm_instance **out) { return ltm_err_ok; } -void ltm_instance_free(ltm_instance *instance) { - if (instance->vars != NULL) { - free(instance->vars); - } - - ltm_instance_block *block = instance->blocks.head; - - while (block != NULL) { - switch (block->type) { - case ltm_instance_block_type_buf_owned: - free(block->data.ptr); - break; - case ltm_instance_block_type_nested: - ltm_instance_free(block->data.ptr); - break; - case ltm_instance_block_type_buf:; - } - - ltm_instance_block *temp = block->next; - free(block); - block = temp; - } - - free(instance); -} - ltm_err ltm_template_instantiate(ltm_instance **out, const ltm_template *template) { ltm_instance *instance; @@ -62,20 +32,15 @@ ltm_err ltm_template_instantiate(ltm_instance **out, instance->template = template; - ltm_instance_block ***vars = NULL; + ltm_instance_block ***vars = + malloc(template->names.len * sizeof(ltm_instance_block **)); - if (template->names.len > 0) { - vars = malloc(template->names.len * sizeof(ltm_instance_block **)); - - if (vars == NULL) { - ltm_instance_free(instance); - - return ltm_err_failed_alloc; - } - - instance->vars = vars; + 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]; @@ -83,7 +48,7 @@ ltm_err ltm_template_instantiate(ltm_instance **out, switch (template_block->type) { case ltm_template_block_type_literal: { ltm_instance_block *block; - LTM_RES2(ltm_instance_block_init(&block), ltm_instance_free(instance)); + LTM_RES(ltm_instance_block_init(&block)); block->type = ltm_instance_block_type_buf; block->data.ptr = template_block->data.ptr; @@ -102,7 +67,6 @@ ltm_err ltm_template_instantiate(ltm_instance **out, case ltm_template_block_type_nested: *vars = &instance->blocks.tail->next; vars++; - break; } } @@ -110,151 +74,3 @@ ltm_err ltm_template_instantiate(ltm_instance **out, return ltm_err_ok; } - -ltm_err ltm_instance_block_add_var(ltm_instance *instance, const char *name, - ltm_instance_block_type type, void *data, - size_t len) { - const ltm_template *template = instance->template; - - ltm_template_block_name *block_name = NULL; - size_t i = 0; - - for (i = 0; i < template->names.len; i++) { - block_name = &template->names.arr[i]; - - if (strncmp(name, block_name->name.s, block_name->name.len) == 0) { - break; - } - } - - if (i == template->names.len) { - return ltm_err_not_found; - } - - ltm_template_block *template_block = &template->blocks.arr[block_name->index]; - - if (template_block->type != ltm_template_block_type_var) { - return ltm_err_wrong_block_type; - } - - ltm_instance_block *block; - LTM_RES(ltm_instance_block_init(&block)); - - block->type = type; - block->data.ptr = data; - block->data.len = len; - - // We insert the block in the linked list and replace its next pointer as the - // new attachment point for this variable - block->next = *instance->vars[i]; - *instance->vars[i] = block; - instance->vars[i] = &block->next; - - return ltm_err_ok; -} - -ltm_err ltm_instance_block_add_nested(ltm_instance **out, - ltm_instance *instance, - const char *name) { - const ltm_template *template = instance->template; - bool matched = false; - - size_t i = 0; - for (i = 0; i < template->names.len && !matched; i++) { - ltm_template_block_name *block_name = &template->names.arr[i]; - matched = strncmp(name, block_name->name.s, block_name->name.len) == 0; - } - - if (!matched) { - return ltm_err_not_found; - } - - ltm_template_block *template_block = &template->blocks.arr[i]; - - if (template_block->type != ltm_template_block_type_nested) { - return ltm_err_wrong_block_type; - } - - ltm_instance_block *block; - LTM_RES(ltm_instance_block_init(&block)); - - ltm_instance *nested; - LTM_RES2(ltm_template_instantiate(&nested, template_block->data.ptr), - free(block)); - - block->type = ltm_instance_block_type_nested; - block->data.ptr = nested; - - // We insert the block in the linked list and replace its next pointer as the - // new attachment point for this variable - block->next = *instance->vars[i]; - *instance->vars[i] = block; - instance->vars[i] = &block->next; - - *out = nested; - - return ltm_err_ok; -} - -size_t ltm_instance_size(const ltm_instance *instance) { - size_t total = 0; - ltm_instance_block *block = instance->blocks.head; - - while (block != NULL) { - switch (block->type) { - case ltm_instance_block_type_buf: - case ltm_instance_block_type_buf_owned: - total += block->data.len; - break; - case ltm_instance_block_type_nested: - total += ltm_instance_size(block->data.ptr); - break; - } - - block = block->next; - } - - return total; -} - -ltm_err ltm_instance_write(size_t *written, char *buf, size_t len, - ltm_instance *instance) { - while ((*written < len) && (instance->blocks.current != NULL)) { - ltm_instance_block *current = instance->blocks.current; - - switch (current->type) { - case ltm_instance_block_type_buf: - case ltm_instance_block_type_buf_owned: { - size_t cap = - LTM_MIN(current->data.len - instance->written, len - *written); - memcpy(&buf[*written], current->data.ptr, cap); - *written += cap; - instance->written += cap; - - if (instance->written == current->data.len) { - instance->blocks.current = current->next; - instance->written = 0; - } - } break; - case ltm_instance_block_type_nested: { - size_t nested_written = 0; - ltm_err res = ltm_instance_write(&nested_written, &buf[*written], - len - *written, current->data.ptr); - *written += nested_written; - - switch (res) { - case ltm_err_done: - instance->blocks.current = current->next; - instance->written = 0; - break; - case ltm_err_ok: - break; - default: - return res; - } - } break; - } - } - - return instance->blocks.current == NULL ? ltm_err_done : ltm_err_ok; -} diff --git a/ltm/src/ltm_template.c b/ltm/src/ltm_template.c index 03dcbd3..13ab14a 100644 --- a/ltm/src/ltm_template.c +++ b/ltm/src/ltm_template.c @@ -13,30 +13,6 @@ ltm_err ltm_template_init(ltm_template **out) { return ltm_err_ok; } -void ltm_template_free(ltm_template *template) { - if (template->blocks.len > 0) { - for (size_t i = 0; i < template->blocks.len; i++) { - ltm_template_block *block = &template->blocks.arr[i]; - - switch (block->type) { - case ltm_template_block_type_nested: - ltm_template_free(block->data.ptr); - break; - case ltm_template_block_type_var: - case ltm_template_block_type_literal:; - } - } - - free(template->blocks.arr); - } - - if (template->names.len > 0) { - free(template->names.arr); - } - - free(template); -} - ltm_err ltm_template_name_append(ltm_template *template, const char *s, size_t len, size_t index) { ltm_template_block_name *names = diff --git a/ltm/src/ltm_template_compile.c b/ltm/src/ltm_template_compile.c index b69aa4b..7093093 100644 --- a/ltm/src/ltm_template_compile.c +++ b/ltm/src/ltm_template_compile.c @@ -104,26 +104,20 @@ ltm_err ltm_template_compile_n(ltm_template **out, const char *s, size_t len) { while (ltm_template_next_placeholder(&ph, s, len)) { // Add part before placeholder as literal if (!in_nested && (ph.start != s)) { - LTM_RES2(ltm_template_block_append(template, - ltm_template_block_type_literal, - (void *)s, ph.start - s), - ltm_template_free(template)); + LTM_RES(ltm_template_block_append( + template, ltm_template_block_type_literal, (void *)s, ph.start - s)); } switch (ph.type) { // Invalid placeholders can be detected as early as possible case ltm_placeholder_type_invalid: - ltm_template_free(template); - return ltm_err_invalid_template; case ltm_placeholder_type_var: if (!in_nested) { - LTM_RES2(ltm_template_block_append( - template, ltm_template_block_type_var, NULL, 0), - ltm_template_free(template)); - LTM_RES2(ltm_template_name_append(template, ph.name.s, ph.name.len, - template->blocks.len - 1), - ltm_template_free(template)); + LTM_RES(ltm_template_block_append(template, ltm_template_block_type_var, + NULL, 0)); + LTM_RES(ltm_template_name_append(template, ph.name.s, ph.name.len, + template->blocks.len - 1)); } break; case ltm_placeholder_type_nested_start: @@ -139,8 +133,6 @@ ltm_err ltm_template_compile_n(ltm_template **out, const char *s, size_t len) { case ltm_placeholder_type_nested_end: // This means there's more nested end placeholders than nested starts if (cur_nested_depth == 0) { - ltm_template_free(template); - return ltm_err_invalid_template; } @@ -149,22 +141,17 @@ ltm_err ltm_template_compile_n(ltm_template **out, const char *s, size_t len) { if (in_nested && (cur_nested_depth == nested_depth)) { size_t nested_len = ph.start - nested_start; ltm_template *nested_template; - LTM_RES2( - ltm_template_compile_n(&nested_template, nested_start, nested_len), - ltm_template_free(template)); + LTM_RES( + ltm_template_compile_n(&nested_template, nested_start, nested_len)); LTM_RES(ltm_template_block_append( template, ltm_template_block_type_nested, nested_template, 0)); - LTM_RES2(ltm_template_name_append(template, nested_name, - nested_name_len, - template->blocks.len - 1), - ltm_template_free(template)); + LTM_RES(ltm_template_name_append(template, nested_name, nested_name_len, + template->blocks.len - 1)); in_nested = false; } // We encountered a nested end without a start else if (!in_nested) { - ltm_template_free(template); - return ltm_err_invalid_template; } break; @@ -176,16 +163,13 @@ ltm_err ltm_template_compile_n(ltm_template **out, const char *s, size_t len) { // Unfinished nested if (in_nested) { - ltm_template_free(template); - return ltm_err_invalid_template; } // Add remaining trailing literal if (len > 0) { - LTM_RES2(ltm_template_block_append( - template, ltm_template_block_type_literal, (void *)s, len), - ltm_template_free(template)); + LTM_RES(ltm_template_block_append(template, ltm_template_block_type_literal, + (void *)s, len)); } *out = template; diff --git a/ltm/test/template_compile.c b/ltm/test/compile.c similarity index 97% rename from ltm/test/template_compile.c rename to ltm/test/compile.c index 127b5fc..c7c7151 100644 --- a/ltm/test/template_compile.c +++ b/ltm/test/compile.c @@ -1,6 +1,6 @@ +#include "ltm/common.h" #include "test.h" -#include "ltm/common.h" #include "ltm/template.h" #include "ltm/template_internal.h" @@ -23,8 +23,6 @@ void test_single_placeholder() { TEST_CHECK(template->names.arr[0].name.s == s + 10); TEST_CHECK(template->names.arr[0].name.len == 5); TEST_CHECK(template->names.arr[0].index == 1); - - ltm_template_free(template); } void test_single_placeholder_trailing() { @@ -50,8 +48,6 @@ void test_single_placeholder_trailing() { TEST_CHECK(template->names.arr[0].name.s == s + 10); TEST_CHECK(template->names.arr[0].name.len == 5); TEST_CHECK(template->names.arr[0].index == 1); - - ltm_template_free(template); } void test_single_nested() { @@ -87,8 +83,6 @@ void test_single_nested() { TEST_CHECK(nested_template->names.arr[0].name.s == s + 33); TEST_CHECK(nested_template->names.arr[0].name.len == 3); TEST_CHECK(nested_template->names.arr[0].index == 1); - - ltm_template_free(template); } void test_unclosed_placeholder() { diff --git a/ltm/test/instance.c b/ltm/test/instance.c deleted file mode 100644 index b2a978b..0000000 --- a/ltm/test/instance.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "test.h" - -#include "ltm/common.h" -#include "ltm/template.h" -#include "ltm/template_internal.h" - -void test_single_placeholder() { - const char *s = "Hello, {{ world }}!"; - - ltm_template *template; - TEST_ASSERT(ltm_template_compile(&template, s) == ltm_err_ok); - - ltm_instance *instance; - TEST_CHECK(ltm_template_instantiate(&instance, template) == ltm_err_ok); - - TEST_CHECK(ltm_instance_block_add_var(instance, "world", ltm_instance_block_type_buf, "World", 5) == ltm_err_ok); - - TEST_CHECK(ltm_instance_size(instance) == 13); - - char buf[13]; - size_t written = 0; - TEST_CHECK(ltm_instance_write(&written, buf, 13, instance) == ltm_err_done); - TEST_CHECK(written == 13); - TEST_CHECK(strncmp(buf, "Hello, World!", 13) == 0); - - ltm_instance_free(instance); - ltm_template_free(template); -} - -TEST_LIST = { - { "instance single placeholder", test_single_placeholder }, - { NULL, NULL } -};