From 8d74fd5b0e5fc9f319a5b7d2e0716afcc312fd75 Mon Sep 17 00:00:00 2001 From: Danny van Kooten Date: Wed, 18 Mar 2020 19:21:48 +0100 Subject: clean-up environment in env_free(). add hashmap_walk function for visiting all values in a hashmap. --- src/hashmap.c | 16 ++++++++- src/hashmap.h | 3 +- src/parser.c | 94 --------------------------------------------------- src/template.c | 21 ++++++++++-- tests/test_template.c | 7 ++-- 5 files changed, 38 insertions(+), 103 deletions(-) delete mode 100644 src/parser.c diff --git a/src/hashmap.c b/src/hashmap.c index f99ba4c..600a005 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -51,7 +51,7 @@ void *hashmap_get(struct hashmap *hm, char *key) { int pos = HASH(key); struct node *node = hm->buckets[pos]; while (node) { - if (strcmp(node->key, key) == 0) { + if (node->key && strcmp(node->key, key) == 0) { return node->value; } @@ -112,6 +112,20 @@ void *hashmap_remove(struct hashmap *hm, char *key) { return NULL; } +void hashmap_walk(struct hashmap *hm, void (*fn)(void *value)) { + struct node *node; + struct node *next; + + for (int i=0; i < HASHMAP_CAP; i++) { + node = hm->buckets[i]; + while (node) { + next = node->next; + fn(node->value); + node = next; + } + } +} + /* free hashmap related memory */ void hashmap_free(struct hashmap *hm) { struct node *node; diff --git a/src/hashmap.h b/src/hashmap.h index be2b80e..dbb45da 100644 --- a/src/hashmap.h +++ b/src/hashmap.h @@ -9,4 +9,5 @@ void *hashmap_insert(struct hashmap *hm, char *key, void *value); void *hashmap_get(struct hashmap *hm, char *key); void *hashmap_resolve(struct hashmap *hm, char *key); void *hashmap_remove(struct hashmap *hm, char *key); -void hashmap_free(struct hashmap *hm); \ No newline at end of file +void hashmap_free(struct hashmap *hm); +void hashmap_walk(struct hashmap *hm, void (*fn)(void *value)); \ No newline at end of file diff --git a/src/parser.c b/src/parser.c deleted file mode 100644 index e61b1e5..0000000 --- a/src/parser.c +++ /dev/null @@ -1,94 +0,0 @@ - -#include -#include - -struct text { - char *str; -}; - -struct symbol { - char *value; -}; - -struct expression { - struct symbol symbol; -}; - -struct statement { - -}; - -/* discard during parsing phase */ -struct comment {}; - - -enum node_type { - NODE_EXPR, - NODE_COMMENT, - NODE_TEXT, -}; - -struct node { - enum node_type type; - union content { - struct expression expr; - struct comment comment; - struct text text; - } content; -}; - -struct ast { - int size; - int cap; - struct node **nodes; -}; - -enum token_type { - TOK_EOF, - TOK_EXPR_OPEN, - TOK_EXPR_CLOSE, - TOK_COMMENT_OPEN, - TOK_COMMENT_CLOSE, - TOK_STMT_OPEN, - TOK_STMT_CLOSE, - TOK_MINUS, - TOK_SYMBOL, - TOK_TEXT, -}; - -struct token { - enum token_type type; - char *literal; -}; - -struct token gettoken(char *str) { - struct token t; - switch (str[0]) { - case '{': - - break; - - case '}': - - break; - - case '\0': - t.type = TOK_EOF; - break; - } - - return t; -}; - -struct ast* parse(char *str) { - struct ast* ast = malloc(sizeof *ast); - ast->size = 0; - ast->cap = 64; - ast->nodes = malloc(ast->cap * sizeof *ast->nodes); - - for (struct token t = gettoken(str); t.type != TOK_EOF; t= gettoken(str)) { - - } - - return ast; -} \ No newline at end of file diff --git a/src/template.c b/src/template.c index 7ea4d05..a1b3ef4 100644 --- a/src/template.c +++ b/src/template.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "vendor/mpc.h" #include "template.h" @@ -167,9 +168,13 @@ struct env *env_new(char *dirname) { continue; } - char *name = de->d_name; + // copy template name as closedir free's it otherwise + char *name = malloc(strlen(de->d_name) + 1); + strcpy(name, de->d_name); + char *tmpl = read_file(name); mpc_ast_t *ast = parse(tmpl); + free(tmpl); struct template *t = malloc(sizeof *t); t->ast = ast; @@ -182,14 +187,24 @@ struct env *env_new(char *dirname) { } hashmap_insert(env->templates, name, t); + } closedir(dr); return env; } +void template_free(void *v) { + struct template *t = (struct template *)v; + hashmap_free(t->blocks); + mpc_ast_delete(t->ast); + free(t->name); + free(t); +} + void env_free(struct env *env) { - // TODO: Free template strings + hashmap_walk(env->templates, template_free); + hashmap_free(env->templates); free(env); } @@ -215,7 +230,7 @@ char *read_file(char *filename) { } char *trim_trailing_whitespace(char *str) { - for (int i=strlen(str)-1; isspace(str[i]); i--) { + for (int i=strlen(str)-1; i >= 0 && isspace(str[i]); i--) { str[i] = '\0'; } return str; diff --git a/tests/test_template.c b/tests/test_template.c index 34022fa..b427f7c 100644 --- a/tests/test_template.c +++ b/tests/test_template.c @@ -182,14 +182,13 @@ TEST(for_block_whitespace) { TEST(var_dot_notation) { char *input = "Hello {{user.name}}!"; - struct hashmap *user = hashmap_new(); - hashmap_insert(user, "name", "Danny"); - struct hashmap *ctx = hashmap_new(); + struct hashmap *user = hashmap_new(); + hashmap_insert(user, "name", "Danny"); hashmap_insert(ctx, "user", user); - char *output = template_string(input, ctx); assert_str(output, "Hello Danny!"); + hashmap_free(user); hashmap_free(ctx); free(output); } -- cgit v1.2.3