aboutsummaryrefslogtreecommitdiff
path: root/src/template.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2024-06-20 15:10:56 -0400
committerGitHub <noreply@github.com>2024-06-20 15:10:56 -0400
commit931ee28eb9c5b5e3c2b0d3008f5f65d810dc9b0c (patch)
tree5dbcccffd509fa71a99c351ed4628ed0841e1e46 /src/template.c
parent11aa1d44d95da221073e512fbec3bbccc0f1a46b (diff)
downloadstasis-931ee28eb9c5b5e3c2b0d3008f5f65d810dc9b0c.tar.gz
Unit tests (#6)
* Initial commit of unit tests [WIP] * Address shortcomings and bugs flushed out by unit tests * Enable unit testing in CI workflow * Enable verbose ctests * Handle lack of __FILE_NAME__ define * Only podman support `run --arch` argument * Skip docker build testing if CI system cannot pull an image * Remove errant call to puts() * Identify local repo user * Fix missing xmllint * NULL terminate arrays * Fix filename assignment in is_url mode * Break loop when expected lines are exhausted * strcmp_array expects NULL terminated array. Iterating by size in this case passes NULL to strcmp leading to an invalid read * Remove debug printf statements * Disable a few warnings for tests * Workaround for ctest junit xml truncation * Update checkout@v4 * Prevent false-positive result * Return zero on error * Fix strlist_remove function * Value argument can be constant * Fix test to match changes to startswith and endswith * Add test_ini.c * Fix redaction code to accept NULL pointers in array * And let the caller specify the length of the array of strings to redact. * Redactions now occur directly on authentication strings rather than their command line arguments * Fix BUILD_TESTING_DEBUG * Adds missing -D argument
Diffstat (limited to 'src/template.c')
-rw-r--r--src/template.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/src/template.c b/src/template.c
index 6101338..0a57232 100644
--- a/src/template.c
+++ b/src/template.c
@@ -16,9 +16,14 @@ struct tpl_item {
};
struct tpl_item *tpl_pool[1024] = {0};
unsigned tpl_pool_used = 0;
+struct tplfunc_frame *tpl_pool_func[1024] = {0};
unsigned tpl_pool_func_used = 0;
-struct tplfunc_frame *tpl_pool_func[1024] = {0};
+extern void tpl_reset() {
+ tpl_free();
+ tpl_pool_used = 0;
+ tpl_pool_func_used = 0;
+}
void tpl_register_func(char *key, struct tplfunc_frame *frame) {
(void) key; // TODO: placeholder
@@ -86,6 +91,10 @@ void tpl_free() {
}
guard_free(item);
}
+ for (unsigned i = 0; i < tpl_pool_func_used; i++) {
+ struct tplfunc_frame *item = tpl_pool_func[i];
+ guard_free(item);
+ }
}
char *tpl_getval(char *key) {
@@ -167,7 +176,9 @@ char *tpl_render(char *str) {
size_t key_len = 0;
while (isalnum(pos[off]) || pos[off] != '}') {
if (isspace(pos[off]) || isblank(pos[off])) {
- break;
+ // skip whitespace in key
+ off++;
+ continue;
}
key[key_len] = pos[off];
key_len++;
@@ -205,7 +216,44 @@ char *tpl_render(char *str) {
char *env_val = getenv(key);
value = strdup(env_val ? env_val : "");
} else if (do_func) { // {{ func:NAME(a, ...) }}
- // TODO
+ char func_name_temp[OMC_NAME_MAX] = {0};
+ strcpy(func_name_temp, type_stop + 1);
+ char *param_begin = strchr(func_name_temp, '(');
+ if (!param_begin) {
+ fprintf(stderr, "offset %zu: function name must be followed by a '('\n", off);
+ guard_free(output);
+ return NULL;
+ }
+ *param_begin = 0;
+ param_begin++;
+ char *param_end = strrchr(param_begin, ')');
+ if (!param_end) {
+ fprintf(stderr, "offset %zu: function arguments must be closed with a ')'\n", off);
+ guard_free(output);
+ return NULL;
+ }
+ *param_end = 0;
+ char *k = func_name_temp;
+ char **params = split(param_begin, ",", 0);
+ int params_count;
+ for (params_count = 0; params[params_count] != NULL; params_count++);
+
+ struct tplfunc_frame *frame = tpl_getfunc(k);
+ if (params_count > frame->argc) {
+ fprintf(stderr, "offset %zu: Too many arguments for function: %s()\n", off, frame->key);
+ value = strdup("");
+ } else {
+ for (size_t p = 0; p < sizeof(frame->argv) / sizeof(*frame->argv) && params[p] != NULL; p++) {
+ lstrip(params[p]);
+ strip(params[p]);
+ frame->argv[p].t_char_ptr = params[p];
+ }
+ char func_result[100];
+ char *fres = func_result;
+ frame->func(frame, fres);
+ value = strdup(fres);
+ }
+ GENERIC_ARRAY_FREE(params);
} else {
// Read replacement value
value = strdup(tpl_getval(key) ? tpl_getval(key) : "");