diff --git a/ltm/src/_include/ltm/template_internal.h b/ltm/src/_include/ltm/template_internal.h index 4c651ae..f095183 100644 --- a/ltm/src/_include/ltm/template_internal.h +++ b/ltm/src/_include/ltm/template_internal.h @@ -96,6 +96,12 @@ typedef struct ltm_instance_block { ltm_err ltm_instance_block_init(ltm_instance_block **out); +/** + * Add a new block to the instance with the given type. + */ +ltm_err ltm_instance_block_add(ltm_instance_block **out, ltm_instance *instance, + const char *name, ltm_instance_block_type type); + struct ltm_instance { const ltm_template *template; struct { diff --git a/ltm/src/ltm_instance.c b/ltm/src/ltm_instance.c index f0c27fa..1c23bd7 100644 --- a/ltm/src/ltm_instance.c +++ b/ltm/src/ltm_instance.c @@ -106,7 +106,9 @@ ltm_err ltm_template_instantiate(ltm_instance **out, } break; case ltm_template_block_type_var: case ltm_template_block_type_nested: - *vars = &instance->blocks.tail->next; + // Account for the possibility a template starts with a placeholder + *vars = instance->blocks.tail != NULL ? &instance->blocks.tail->next + : &instance->blocks.head; vars++; break; } @@ -117,20 +119,21 @@ 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) { +ltm_err ltm_instance_block_add(ltm_instance_block **out, ltm_instance *instance, + const char *name, ltm_instance_block_type type) { 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++) { + while (i < template->names.len) { block_name = &template->names.arr[i]; if (strncmp(name, block_name->name.s, block_name->name.len) == 0) { break; } + + i++; } if (i == template->names.len) { @@ -138,8 +141,22 @@ ltm_err ltm_instance_block_add_var(ltm_instance *instance, const char *name, } ltm_template_block *template_block = &template->blocks.arr[block_name->index]; + bool correct_type = false; - if (template_block->type != ltm_template_block_type_var) { + switch (type) { + case ltm_instance_block_type_nested: + correct_type = template_block->type == ltm_template_block_type_nested; + break; + case ltm_instance_block_type_buf: + case ltm_instance_block_type_buf_owned: + case ltm_instance_block_type_file: + case ltm_instance_block_type_file_owned: + case ltm_instance_block_type_fn: + correct_type = template_block->type == ltm_template_block_type_var; + break; + } + + if (!correct_type) { return ltm_err_wrong_block_type; } @@ -147,57 +164,39 @@ ltm_err ltm_instance_block_add_var(ltm_instance *instance, const char *name, 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 + // Insert the block in the linked list block->next = *instance->vars[i]; *instance->vars[i] = block; instance->vars[i] = &block->next; + *out = block; + + 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) { + ltm_instance_block *block; + LTM_RES(ltm_instance_block_add(&block, instance, name, type)); + + block->data.ptr = data; + block->data.len = len; + return ltm_err_ok; } ltm_err ltm_instance_block_add_var_fn(ltm_instance *instance, const char *name, ltm_data_fn fn, 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)); + LTM_RES(ltm_instance_block_add(&block, instance, name, + ltm_instance_block_type_fn)); - block->type = ltm_instance_block_type_fn; block->fn = fn; 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; } @@ -205,19 +204,25 @@ 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; + ltm_template_block_name *block_name = NULL; 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; + + while (i < template->names.len) { + block_name = &template->names.arr[i]; + + if (strncmp(name, block_name->name.s, block_name->name.len) == 0) { + break; + } + + i++; } - if (!matched) { + if (i == template->names.len) { return ltm_err_not_found; } - ltm_template_block *template_block = &template->blocks.arr[i]; + ltm_template_block *template_block = &template->blocks.arr[block_name->index]; if (template_block->type != ltm_template_block_type_nested) { return ltm_err_wrong_block_type;