aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--src/hyde.c117
-rw-r--r--src/template.c112
-rw-r--r--src/template.h9
-rw-r--r--tests/test.h9
-rw-r--r--tests/test_hashmap.c8
-rw-r--r--tests/test_template.c10
7 files changed, 149 insertions, 123 deletions
diff --git a/Makefile b/Makefile
index 5425eb2..a362f52 100644
--- a/Makefile
+++ b/Makefile
@@ -6,14 +6,17 @@ all: bin/hyde
bin:; mkdir -p bin/
-bin/hyde: src/hyde.c src/hashmap.c vendor/mpc.c | bin
+bin/hyde: src/hyde.c src/hashmap.c src/template.c vendor/mpc.c | bin
$(CC) $(CFLAGS) $^ -o $@
bin/test_hashmap: src/hashmap.c tests/test_hashmap.c | bin
$(CC) $(TESTFLAGS) $^ -o $@
+bin/test_template: src/template.c src/hashmap.c tests/test_template.c vendor/mpc.c | bin
+ $(CC) $(TESTFLAGS) $^ -o $@
+
.PHONY: check
-check: bin/test_hashmap
+check: bin/test_hashmap bin/test_template
for test in $^; do $$test || exit 1; done
.PHONY: clean
diff --git a/src/hyde.c b/src/hyde.c
index 332ddab..172f15d 100644
--- a/src/hyde.c
+++ b/src/hyde.c
@@ -1,120 +1,5 @@
-#include <stdio.h>
+#include "template.h"
#include <stdlib.h>
-#include "vendor/mpc.h"
-#include "hashmap.h"
-
-
-struct post {
- char title[64];
- char tags[8][32];
-};
-
-char *read_file(char *filename) {
- char *input = malloc(BUFSIZ);
- unsigned int size = 0;
-
- FILE *f = fopen(filename, "r");
- if (!f) {
- printf("Could not open \"%s\" for reading", filename);
- exit(1);
- }
-
- unsigned int read = 0;
- while ( (read = fread(input, 1, BUFSIZ, f)) > 0) {
- size += read;
- input = realloc(input, size + BUFSIZ);
- }
-
- fclose(f);
-
- input[size] = '\0';
- return input;
-}
-
-int eval(char *dest, mpc_ast_t* t, struct hashmap *ctx) {
- printf("%s: %s\n", t->tag, t->contents);
-
- if (strstr(t->tag, "content|text")) {
- strcat(dest, t->contents);
- return 0;
- }
-
- if (strstr(t->tag, "content|var")) {
- printf("Key: %s\n", t->contents);
- char *value = hashmap_get(ctx, t->children[1]->contents);
- if (value == NULL) {
- return 1;
- }
- strcat(dest, value);
- return 0;
- }
-
- if (strstr(t->tag, "content|for")) {
- char *tmp_key = t->children[2]->contents;
- char *iterator_key = t->children[4]->contents;
- // TODO: Make this dynamic
- struct post **posts = hashmap_get(ctx, iterator_key);
- for (int i=0; i < 2; i++) {
- hashmap_insert(ctx, tmp_key, posts[i]);
- eval(dest, t->children[6], ctx);
- }
- return 0;
- }
-
- for (int i=0; i < t->children_num; i++) {
- eval(dest, t->children[i], ctx);
- }
-
- return 0;
-}
-
-mpc_parser_t *parser_init() {
- mpc_parser_t *Symbol = mpc_new("symbol");
- mpc_parser_t *Text = mpc_new("text");
- mpc_parser_t *Var_Open = mpc_new("var_open");
- mpc_parser_t *Var_Close = mpc_new("var_close");
- mpc_parser_t *Var = mpc_new("var");
- mpc_parser_t *Block_Open = mpc_new("block_open");
- mpc_parser_t *Block_Close = mpc_new("block_close");
- mpc_parser_t *For = mpc_new("for");
- mpc_parser_t *Content = mpc_new("content");
- mpc_parser_t *Template = mpc_new("template");
- mpca_lang(MPCA_LANG_WHITESPACE_SENSITIVE,
- " symbol : /[a-zA-Z._]+/ ;"
- " var_open : /\{{2} ?/ ;"
- " var_close : / ?}{2}/ ;"
- " var : <var_open> <symbol> <var_close> ;"
- " block_open: /\{\% ?/ ;"
- " block_close: / ?\%}/ ;"
- " for : <block_open> \"for \" <symbol> \" in \" <symbol> <block_close> <content>* <block_open> \"endfor\" <block_close> ;"
- " text : /[^{][^{%]*/ ;"
- " content : <var> | <for> | <text>;"
- " template : /^/ <content>* /$/ ;",
- Symbol, Var_Open, Var_Close, Var, Block_Open, Block_Close, For, Text, Content, Template, NULL);
- return Template;
-}
-
-void template(char *tmpl, struct hashmap *ctx) {
- mpc_parser_t *parser = parser_init();
- mpc_result_t r;
-
- if (mpc_parse("input", tmpl, parser, &r)) {
- mpc_ast_print(r.output);
-
- // FIXME: Allocate precisely
- char *output = malloc(strlen(tmpl) * 2);
- output[0] = '\0';
- eval(output, r.output, ctx);
- printf("Template: \n%s", output);
-
- mpc_ast_delete(r.output);
- free(output);
- } else {
- mpc_err_print(r.error);
- mpc_err_delete(r.error);
- }
-}
-
int main() {
char *input = read_file("index.tpl");
diff --git a/src/template.c b/src/template.c
new file mode 100644
index 0000000..5d400b9
--- /dev/null
+++ b/src/template.c
@@ -0,0 +1,112 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "vendor/mpc.h"
+#include "template.h"
+
+char *read_file(char *filename) {
+ char *input = malloc(BUFSIZ);
+ unsigned int size = 0;
+
+ FILE *f = fopen(filename, "r");
+ if (!f) {
+ printf("Could not open \"%s\" for reading", filename);
+ exit(1);
+ }
+
+ unsigned int read = 0;
+ while ( (read = fread(input, 1, BUFSIZ, f)) > 0) {
+ size += read;
+ input = realloc(input, size + BUFSIZ);
+ }
+
+ fclose(f);
+
+ input[size] = '\0';
+ return input;
+}
+
+int eval(char *dest, mpc_ast_t* t, struct hashmap *ctx) {
+ printf("%s: %s\n", t->tag, t->contents);
+
+ if (strstr(t->tag, "content|text")) {
+ strcat(dest, t->contents);
+ return 0;
+ }
+
+ if (strstr(t->tag, "content|var")) {
+ printf("Key: %s\n", t->contents);
+ char *value = hashmap_get(ctx, t->children[1]->contents);
+ if (value == NULL) {
+ return 1;
+ }
+ strcat(dest, value);
+ return 0;
+ }
+
+ if (strstr(t->tag, "content|for")) {
+ char *tmp_key = t->children[2]->contents;
+ char *iterator_key = t->children[4]->contents;
+ // TODO: Make this dynamic
+ struct post **posts = hashmap_get(ctx, iterator_key);
+ for (int i=0; i < 2; i++) {
+ hashmap_insert(ctx, tmp_key, posts[i]);
+ eval(dest, t->children[6], ctx);
+ }
+ return 0;
+ }
+
+ for (int i=0; i < t->children_num; i++) {
+ eval(dest, t->children[i], ctx);
+ }
+
+ return 0;
+}
+
+mpc_parser_t *parser_init() {
+ mpc_parser_t *Symbol = mpc_new("symbol");
+ mpc_parser_t *Text = mpc_new("text");
+ mpc_parser_t *Var_Open = mpc_new("var_open");
+ mpc_parser_t *Var_Close = mpc_new("var_close");
+ mpc_parser_t *Var = mpc_new("var");
+ mpc_parser_t *Block_Open = mpc_new("block_open");
+ mpc_parser_t *Block_Close = mpc_new("block_close");
+ mpc_parser_t *For = mpc_new("for");
+ mpc_parser_t *Content = mpc_new("content");
+ mpc_parser_t *Template = mpc_new("template");
+ mpca_lang(MPCA_LANG_WHITESPACE_SENSITIVE,
+ " symbol : /[a-zA-Z._]+/ ;"
+ " var_open : /\{{2} ?/ ;"
+ " var_close : / ?}{2}/ ;"
+ " var : <var_open> <symbol> <var_close> ;"
+ " block_open: /\{\% ?/ ;"
+ " block_close: / ?\%}/ ;"
+ " for : <block_open> \"for \" <symbol> \" in \" <symbol> <block_close> <content>* <block_open> \"endfor\" <block_close> ;"
+ " text : /[^{][^{%]*/ ;"
+ " content : <var> | <for> | <text>;"
+ " template : /^/ <content>* /$/ ;",
+ Symbol, Var_Open, Var_Close, Var, Block_Open, Block_Close, For, Text, Content, Template, NULL);
+ return Template;
+}
+
+void template(char *tmpl, struct hashmap *ctx) {
+ mpc_parser_t *parser = parser_init();
+ mpc_result_t r;
+
+ if (mpc_parse("input", tmpl, parser, &r)) {
+ mpc_ast_print(r.output);
+
+ // FIXME: Allocate precisely
+ char *output = malloc(strlen(tmpl) * 2);
+ output[0] = '\0';
+ eval(output, r.output, ctx);
+ printf("Template: \n%s", output);
+
+ mpc_ast_delete(r.output);
+ free(output);
+ } else {
+ mpc_err_print(r.error);
+ mpc_err_delete(r.error);
+ }
+}
+
diff --git a/src/template.h b/src/template.h
new file mode 100644
index 0000000..896ef71
--- /dev/null
+++ b/src/template.h
@@ -0,0 +1,9 @@
+#include "hashmap.h"
+
+char *read_file(char *filename);
+void template(char *tmpl, struct hashmap *ctx);
+
+struct post {
+ char title[64];
+ char tags[8][32];
+}; \ No newline at end of file
diff --git a/tests/test.h b/tests/test.h
index 19868f8..05c35b9 100644
--- a/tests/test.h
+++ b/tests/test.h
@@ -3,12 +3,15 @@
#include <stdarg.h>
#include <string.h>
-#define assert(assertion, format, ...) _assert(assertion, __FILE__, __LINE__, format, ##__VA_ARGS__)
-#define TESTNAME(v) strcpy(current_test, v);
+#define START_TESTS int main() {
+#define END_TESTS }
+#define TEST(name) strcpy(current_test, #name);
+/* used to store the running test name */
char current_test[256] = {'\0'};
-void _assert(int assertion, const char filename[64], const int line, char *format, ...)
+#define assert(assertion, format, ...) _assert(assertion, __FILE__, __LINE__, format, ##__VA_ARGS__)
+static void _assert(int assertion, const char filename[64], const int line, char *format, ...)
{
if (assertion)
{
diff --git a/tests/test_hashmap.c b/tests/test_hashmap.c
index cf6f7a2..68b8d0c 100644
--- a/tests/test_hashmap.c
+++ b/tests/test_hashmap.c
@@ -1,7 +1,9 @@
#include "test.h"
#include "hashmap.h"
-int main() {
+START_TESTS
+
+TEST(hashmap) {
struct hashmap *hm = hashmap_new();
assert(hashmap_get(hm, "foo") == NULL, "expected NULL");
@@ -11,4 +13,6 @@ int main() {
assert(strcmp(value, "bar") == 0, "expected %s, got %s", "bar", value);
hashmap_free(hm);
-} \ No newline at end of file
+}
+
+END_TESTS \ No newline at end of file
diff --git a/tests/test_template.c b/tests/test_template.c
new file mode 100644
index 0000000..62ac77c
--- /dev/null
+++ b/tests/test_template.c
@@ -0,0 +1,10 @@
+#include "test.h"
+#include "template.h"
+
+START_TESTS
+
+TEST(text_only) {
+
+}
+
+END_TESTS \ No newline at end of file