From cd70ca266bb212d6a32d2dd808c7708bb7be6f1f Mon Sep 17 00:00:00 2001 From: Danny van Kooten Date: Thu, 12 Mar 2020 09:30:29 +0100 Subject: move files to src/ subdir --- Makefile | 17 ++++--- hashmap.c | 74 ------------------------------ hashmap.h | 10 ----- hyde.c | 142 ---------------------------------------------------------- src/hashmap.c | 74 ++++++++++++++++++++++++++++++ src/hashmap.h | 10 +++++ src/hyde.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 236 insertions(+), 233 deletions(-) delete mode 100644 hashmap.c delete mode 100644 hashmap.h delete mode 100644 hyde.c create mode 100644 src/hashmap.c create mode 100644 src/hashmap.h create mode 100644 src/hyde.c diff --git a/Makefile b/Makefile index 0551369..5425eb2 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,20 @@ -CFLAGS= -g -Wall -std=c11 -Ivendor/ -I. +CFLAGS= -g -Wall -std=c11 -I. LIBS= +TESTFLAGS= $(CFLAGS) -Isrc/ all: bin/hyde -bin: - mkdir -p bin/ +bin:; mkdir -p bin/ -bin/hyde: hyde.c hashmap.c vendor/mpc.c | bin +bin/hyde: src/hyde.c src/hashmap.c vendor/mpc.c | bin $(CC) $(CFLAGS) $^ -o $@ -bin/test_hashmap: hashmap.c tests/test_hashmap.c | bin - $(CC) $(CFLAGS) $^ -o $@ +bin/test_hashmap: src/hashmap.c tests/test_hashmap.c | bin + $(CC) $(TESTFLAGS) $^ -o $@ .PHONY: check check: bin/test_hashmap - for test in $^; do $$test || exit 1; done \ No newline at end of file + for test in $^; do $$test || exit 1; done + +.PHONY: clean +clean:; rm -r bin/ \ No newline at end of file diff --git a/hashmap.c b/hashmap.c deleted file mode 100644 index 3d9edd0..0000000 --- a/hashmap.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include -#include "hashmap.h" - -struct node { - char *key; - void *value; - struct node *next; -}; - -struct hashmap *hashmap_new() { - struct hashmap *hm = malloc(sizeof *hm); - if (!hm) err(EXIT_FAILURE, "out of memory"); - for (int i=0; i < 26; i++) { - hm->buckets[i] = NULL; - } - - return hm; -} - -void hashmap_insert(struct hashmap *hm, char *key, void *value) { - int pos = (key[0] - 'a') % 26; - struct node *head = hm->buckets[pos]; - struct node *node = head; - - while (node) { - if (strcmp(node->key, key) == 0) { - node->value = value; - return; - } - node = node->next; - } - - node = malloc(sizeof *node); - node->key = key; - node->value = value; - node->next = head; - hm->buckets[pos] = node; -} - -void *hashmap_get(struct hashmap *hm, char *key) { - int pos = (key[0] - 'a') % 26; - struct node *node = hm->buckets[pos]; - while (node) { - if (strcmp(node->key, key) == 0) { - return node->value; - } - - node = node->next; - } - - return NULL; -} - -void hashmap_remove(char *key) { - -} - -void hashmap_free(struct hashmap *hm) { - struct node *node; - struct node *next; - - for (int i=0; i < 26; i++) { - node = hm->buckets[i]; - while (node) { - next = node->next; - free(node); - node = next; - } - } - - free(hm); -} \ No newline at end of file diff --git a/hashmap.h b/hashmap.h deleted file mode 100644 index a37d3d6..0000000 --- a/hashmap.h +++ /dev/null @@ -1,10 +0,0 @@ - -struct hashmap { - struct node *buckets[26]; -}; - -void hashmap_insert(struct hashmap *hm, char *key, void *value); -void *hashmap_get(struct hashmap *hm, char *key); -void hashmap_remove(char *key); -struct hashmap *hashmap_new(); -void hashmap_free(struct hashmap *hm); \ No newline at end of file diff --git a/hyde.c b/hyde.c deleted file mode 100644 index 332ddab..0000000 --- a/hyde.c +++ /dev/null @@ -1,142 +0,0 @@ -#include -#include -#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 : ;" - " block_open: /\{\% ?/ ;" - " block_close: / ?\%}/ ;" - " for : \"for \" \" in \" * \"endfor\" ;" - " text : /[^{][^{%]*/ ;" - " content : | | ;" - " template : /^/ * /$/ ;", - 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"); - - struct hashmap *ctx = hashmap_new(); - hashmap_insert(ctx, "title", "Hello world"); - - struct post home = { - .title = "Homepage", - .tags = { - "Tag 1", "Tag 2" - } - }; - hashmap_insert(ctx, "home", &home); - - struct post posts[] = { - { .title = "Post 1", .tags = { "p1t1" } }, - { .title = "Post 2", .tags = { "p2t1" } }, - }; - hashmap_insert(ctx, "posts", &posts); - - template(input, ctx); - hashmap_free(ctx); - free(input); -} \ No newline at end of file diff --git a/src/hashmap.c b/src/hashmap.c new file mode 100644 index 0000000..3d9edd0 --- /dev/null +++ b/src/hashmap.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include "hashmap.h" + +struct node { + char *key; + void *value; + struct node *next; +}; + +struct hashmap *hashmap_new() { + struct hashmap *hm = malloc(sizeof *hm); + if (!hm) err(EXIT_FAILURE, "out of memory"); + for (int i=0; i < 26; i++) { + hm->buckets[i] = NULL; + } + + return hm; +} + +void hashmap_insert(struct hashmap *hm, char *key, void *value) { + int pos = (key[0] - 'a') % 26; + struct node *head = hm->buckets[pos]; + struct node *node = head; + + while (node) { + if (strcmp(node->key, key) == 0) { + node->value = value; + return; + } + node = node->next; + } + + node = malloc(sizeof *node); + node->key = key; + node->value = value; + node->next = head; + hm->buckets[pos] = node; +} + +void *hashmap_get(struct hashmap *hm, char *key) { + int pos = (key[0] - 'a') % 26; + struct node *node = hm->buckets[pos]; + while (node) { + if (strcmp(node->key, key) == 0) { + return node->value; + } + + node = node->next; + } + + return NULL; +} + +void hashmap_remove(char *key) { + +} + +void hashmap_free(struct hashmap *hm) { + struct node *node; + struct node *next; + + for (int i=0; i < 26; i++) { + node = hm->buckets[i]; + while (node) { + next = node->next; + free(node); + node = next; + } + } + + free(hm); +} \ No newline at end of file diff --git a/src/hashmap.h b/src/hashmap.h new file mode 100644 index 0000000..a37d3d6 --- /dev/null +++ b/src/hashmap.h @@ -0,0 +1,10 @@ + +struct hashmap { + struct node *buckets[26]; +}; + +void hashmap_insert(struct hashmap *hm, char *key, void *value); +void *hashmap_get(struct hashmap *hm, char *key); +void hashmap_remove(char *key); +struct hashmap *hashmap_new(); +void hashmap_free(struct hashmap *hm); \ No newline at end of file diff --git a/src/hyde.c b/src/hyde.c new file mode 100644 index 0000000..332ddab --- /dev/null +++ b/src/hyde.c @@ -0,0 +1,142 @@ +#include +#include +#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 : ;" + " block_open: /\{\% ?/ ;" + " block_close: / ?\%}/ ;" + " for : \"for \" \" in \" * \"endfor\" ;" + " text : /[^{][^{%]*/ ;" + " content : | | ;" + " template : /^/ * /$/ ;", + 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"); + + struct hashmap *ctx = hashmap_new(); + hashmap_insert(ctx, "title", "Hello world"); + + struct post home = { + .title = "Homepage", + .tags = { + "Tag 1", "Tag 2" + } + }; + hashmap_insert(ctx, "home", &home); + + struct post posts[] = { + { .title = "Post 1", .tags = { "p1t1" } }, + { .title = "Post 2", .tags = { "p2t1" } }, + }; + hashmap_insert(ctx, "posts", &posts); + + template(input, ctx); + hashmap_free(ctx); + free(input); +} \ No newline at end of file -- cgit v1.2.3