aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am21
-rw-r--r--src/blogc/funcvars.c13
-rw-r--r--src/blogc/funcvars.h2
-rw-r--r--src/blogc/renderer.c6
-rw-r--r--tests/blogc/check_funcvars.c84
6 files changed, 117 insertions, 10 deletions
diff --git a/.gitignore b/.gitignore
index 95082e1..104d634 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,6 +57,7 @@ blogc*.html
/tests/blogc/check_blogc.sh
/tests/blogc/check_content_parser
/tests/blogc/check_datetime_parser
+/tests/blogc/check_funcvars
/tests/blogc/check_loader
/tests/blogc/check_renderer
/tests/blogc/check_source_parser
diff --git a/Makefile.am b/Makefile.am
index 11d9605..f83d6ed 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -478,10 +478,31 @@ check_PROGRAMS += \
if USE_LD_WRAP
check_PROGRAMS += \
+ tests/blogc/check_funcvars \
tests/blogc/check_loader \
tests/common/check_stdin \
$(NULL)
+tests_blogc_check_funcvars_SOURCES = \
+ tests/blogc/check_funcvars.c \
+ $(NULL)
+
+tests_blogc_check_funcvars_CFLAGS = \
+ $(CMOCKA_CFLAGS) \
+ $(NULL)
+
+tests_blogc_check_funcvars_LDFLAGS = \
+ -no-install \
+ -Wl,--wrap=bc_file_get_contents \
+ $(NULL)
+#-Wl,--wrap=bc_file_get_contents
+
+tests_blogc_check_funcvars_LDADD = \
+ $(CMOCKA_LIBS) \
+ libblogc.la \
+ libblogc_common.la \
+ $(NULL)
+
tests_blogc_check_loader_SOURCES = \
tests/blogc/check_loader.c \
$(NULL)
diff --git a/src/blogc/funcvars.c b/src/blogc/funcvars.c
index 25a22bf..42411e2 100644
--- a/src/blogc/funcvars.c
+++ b/src/blogc/funcvars.c
@@ -43,20 +43,23 @@ static const struct func_map {
};
-char*
-blogc_funcvars_lookup(const char *name, bc_trie_t *global)
+void
+blogc_funcvars_eval(bc_trie_t *global, const char *name)
{
+ if (global == NULL || name == NULL)
+ return;
+
// protect against evaluating the same function twice in the same global
// context
if (NULL != bc_trie_lookup(global, name))
- return NULL;
+ return;
for (size_t i = 0; funcs[i].variable != NULL; i++) {
if (0 == strcmp(name, funcs[i].variable)) {
funcs[i].func(global);
- return bc_strdup(bc_trie_lookup(global, name));
+ return;
}
}
- return NULL;
+ return;
}
diff --git a/src/blogc/funcvars.h b/src/blogc/funcvars.h
index f554f8d..aae1bc3 100644
--- a/src/blogc/funcvars.h
+++ b/src/blogc/funcvars.h
@@ -14,6 +14,6 @@
typedef void (*blogc_funcvars_func_t) (bc_trie_t*);
-char* blogc_funcvars_lookup(const char *name, bc_trie_t *global);
+void blogc_funcvars_eval(bc_trie_t *global, const char *name);
#endif /* ___FUNCVARS_H */
diff --git a/src/blogc/renderer.c b/src/blogc/renderer.c
index 2326e09..035f71b 100644
--- a/src/blogc/renderer.c
+++ b/src/blogc/renderer.c
@@ -106,10 +106,8 @@ blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local,
value = foreach_var->data;
}
else {
- value = blogc_funcvars_lookup(var, global);
- if (value == NULL) {
- value = blogc_get_variable(var, global, local);
- }
+ blogc_funcvars_eval(global, var);
+ value = blogc_get_variable(var, global, local);
}
if (value == NULL) {
diff --git a/tests/blogc/check_funcvars.c b/tests/blogc/check_funcvars.c
new file mode 100644
index 0000000..153a870
--- /dev/null
+++ b/tests/blogc/check_funcvars.c
@@ -0,0 +1,84 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "../../src/common/error.h"
+#include "../../src/common/utils.h"
+#include "../../src/blogc/funcvars.h"
+
+
+char*
+__wrap_bc_file_get_contents(const char *path, bool utf8, size_t *len, bc_error_t **err)
+{
+ assert_string_equal(path, "/proc/1/cgroup");
+ assert_false(utf8);
+ char *rv = mock_type(char*);
+ *len = strlen(rv);
+ bc_error_t *e = mock_type(bc_error_t*);
+ if (e != NULL)
+ *err = e;
+ return rv;
+}
+
+
+static void
+test_funcvars_eval(void **state)
+{
+ bc_trie_t *t = bc_trie_new(free);
+ blogc_funcvars_eval(t, NULL);
+ blogc_funcvars_eval(t, "");
+ blogc_funcvars_eval(t, "BOLA");
+ assert_int_equal(bc_trie_size(t), 0);
+
+ bc_trie_insert(t, "BOLA", bc_strdup("GUDA"));
+ blogc_funcvars_eval(t, "BOLA");
+ assert_int_equal(bc_trie_size(t), 1);
+
+ bc_trie_free(t);
+}
+
+
+static void
+test_funcvars_eval_mocked(void **state)
+{
+ bc_trie_t *t = bc_trie_new(free);
+
+ // this is the only function that isn't hidden behind conditional macros
+ // as of when this test was written. the other functions should be tested
+ // separately
+ will_return(__wrap_bc_file_get_contents, bc_strdup("asd/docker/asd"));
+ will_return(__wrap_bc_file_get_contents, NULL);
+ blogc_funcvars_eval(t, "BLOGC_SYSINFO_INSIDE_DOCKER");
+ assert_string_equal(bc_trie_lookup(t, "BLOGC_SYSINFO_INSIDE_DOCKER"), "1");
+ assert_int_equal(bc_trie_size(t), 1);
+
+ // this specific function call is cached, so calling it again should not
+ // call bc_file_get_contents_again
+ blogc_funcvars_eval(t, "BLOGC_SYSINFO_INSIDE_DOCKER");
+ assert_string_equal(bc_trie_lookup(t, "BLOGC_SYSINFO_INSIDE_DOCKER"), "1");
+ assert_int_equal(bc_trie_size(t), 1);
+
+ bc_trie_free(t);
+}
+
+
+int
+main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_funcvars_eval),
+ unit_test(test_funcvars_eval_mocked),
+ };
+ return run_tests(tests);
+}