diff options
| author | Rafael G. Martins <rafael@rafaelmartins.eng.br> | 2015-04-19 00:06:56 -0300 | 
|---|---|---|
| committer | Rafael G. Martins <rafael@rafaelmartins.eng.br> | 2015-04-19 00:06:56 -0300 | 
| commit | 30e5e6890682d4759e6dcdfc833a666e0ab3f7a2 (patch) | |
| tree | d225bd39fcf99b14bc5f9ad8c1bfeedb2d5ab04d | |
| parent | de39a41da62c4b3820b4805ddb7c4970c36bc257 (diff) | |
| download | blogc-30e5e6890682d4759e6dcdfc833a666e0ab3f7a2.tar.gz blogc-30e5e6890682d4759e6dcdfc833a666e0ab3f7a2.tar.bz2 blogc-30e5e6890682d4759e6dcdfc833a666e0ab3f7a2.zip | |
added renderer, without tests
| -rw-r--r-- | Makefile.am | 2 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | src/main.c | 5 | ||||
| -rw-r--r-- | src/renderer.c | 145 | ||||
| -rw-r--r-- | src/renderer.h | 17 | ||||
| -rw-r--r-- | src/template-parser.c | 11 | 
6 files changed, 178 insertions, 4 deletions
| diff --git a/Makefile.am b/Makefile.am index 3b15057..6e6bd96 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,6 +22,7 @@ CLEANFILES = \  noinst_HEADERS = \  	src/error.h \  	src/loader.h \ +	src/renderer.h \  	src/source-parser.h \  	src/template-parser.h \  	src/utils/utils.h \ @@ -45,6 +46,7 @@ check_PROGRAMS = \  libblogc_la_SOURCES = \  	src/error.c \  	src/loader.c \ +	src/renderer.c \  	src/source-parser.c \  	src/template-parser.c \  	src/utils/slist.c \ @@ -61,7 +61,7 @@ Pre-formatted content is available in template blocks as the ``CONTENT`` variabl          {% block single_source %}          <title>My cool blog >> {{ TITLE }}</title>          {% endblock %} -        {% block multiple_sources %} +        {% block multiple_sources_once %}          <title>My cool blog - Main page</title>          {% endblock %}      </head> @@ -18,6 +18,7 @@  #include "source-parser.h"  #include "template-parser.h"  #include "loader.h" +#include "renderer.h"  #include "error.h" @@ -102,7 +103,9 @@ main(int argc, char **argv)          goto cleanup3;      } -    printf("%d\n", s == NULL); +    char *out = blogc_render(l, s); +    printf("%s", out); +    free(out);  cleanup3:      b_slist_free_full(s, blogc_source_free); diff --git a/src/renderer.c b/src/renderer.c new file mode 100644 index 0000000..7d20b39 --- /dev/null +++ b/src/renderer.c @@ -0,0 +1,145 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2015 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file COPYING. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <string.h> +#include "utils/utils.h" +#include "source-parser.h" +#include "template-parser.h" +#include "renderer.h" + + +char* +blogc_render(b_slist_t *tmpl, b_slist_t *sources) +{ +    if (tmpl == NULL || sources == NULL) +        return NULL; + +    bool single_source = sources->next == NULL; + +    b_slist_t *current_source = NULL; +    b_slist_t *multiple_sources_start = NULL; + +    b_string_t *str = b_string_new(); + +    blogc_source_t *tmp_source = NULL; +    char *config_value = NULL; + +    unsigned int if_count = 0; +    unsigned int if_skip = 0; + +    b_slist_t *tmp = tmpl; +    while (tmp != NULL) { +        blogc_template_stmt_t *stmt = tmp->data; + +        switch (stmt->type) { + +            case BLOGC_TEMPLATE_CONTENT_STMT: +                if (stmt->value != NULL) +                    b_string_append(str, stmt->value); +                break; + +            case BLOGC_TEMPLATE_BLOCK_STMT: +                if_count = 0; +                if (0 == strcmp("single_source", stmt->value)) { +                    if (!single_source) { + +                        // we can just skip anything and walk until the next +                        // 'endblock' +                        while (stmt->type != BLOGC_TEMPLATE_ENDBLOCK_STMT) { +                            tmp = tmp->next; +                            stmt = tmp->data; +                        } +                        break; +                    } +                    current_source = sources; +                    tmp_source = current_source->data; +                } +                else if ((0 == strcmp("multiple_sources", stmt->value)) || +                         (0 == strcmp("multiple_sources_once", stmt->value))) { +                    if (single_source) { + +                        // we can just skip anything and walk until the next +                        // 'endblock' +                        while (stmt->type != BLOGC_TEMPLATE_ENDBLOCK_STMT) { +                            tmp = tmp->next; +                            stmt = tmp->data; +                        } +                        break; +                    } +                } +                if (0 == strcmp("multiple_sources", stmt->value)) { +                    if (current_source == NULL) { +                        multiple_sources_start = tmp; +                        current_source = sources; +                    } +                    tmp_source = current_source->data; +                } +                break; + +            case BLOGC_TEMPLATE_VARIABLE_STMT: +                if (stmt->value != NULL && tmp_source != NULL) { +                    config_value = b_trie_lookup(tmp_source->config, stmt->value); +                    if (config_value != NULL) +                        b_string_append(str, config_value); +                    break; +                } +                break; + +            case BLOGC_TEMPLATE_ENDBLOCK_STMT: +                if (multiple_sources_start != NULL && current_source != NULL) { +                    current_source = current_source->next; +                    if (current_source != NULL) { +                        tmp = multiple_sources_start; +                        continue; +                    } +                    else +                        multiple_sources_start = NULL; +                } +                break; + +            case BLOGC_TEMPLATE_IF_STMT: +                if (stmt->value != NULL && tmp_source != NULL) { +                    if (b_trie_lookup(tmp_source->config, stmt->value) == NULL) { +                        if_skip = if_count; + +                        // at this point we can just skip anything, counting the +                        // number of 'if's, to know how many 'endif's we need to +                        // skip as well. +                        while (1) { +                            tmp = tmp->next; +                            stmt = tmp->data; +                            if (stmt->type == BLOGC_TEMPLATE_IF_STMT) { +                                if_count++; +                                continue; +                            } +                            if (stmt->type == BLOGC_TEMPLATE_ENDIF_STMT) { +                                if (if_count > if_skip) { +                                    if_count--; +                                    continue; +                                } +                                if (if_count == if_skip) +                                    break; +                            } +                        } +                    } +                } +                break; + +            case BLOGC_TEMPLATE_ENDIF_STMT: +                if_count--; +                break; +        } +        tmp = tmp->next; +    } + +    return b_string_free(str, false); +} diff --git a/src/renderer.h b/src/renderer.h new file mode 100644 index 0000000..473fe0e --- /dev/null +++ b/src/renderer.h @@ -0,0 +1,17 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2015 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file COPYING. + */ + +#ifndef _RENDERER_H +#define _RENDERER_H + +#include "utils/utils.h" + +char* +blogc_render(b_slist_t *tmpl, b_slist_t *sources); + +#endif /* _RENDERER_H */ diff --git a/src/template-parser.c b/src/template-parser.c index 1038190..d176288 100644 --- a/src/template-parser.c +++ b/src/template-parser.c @@ -53,8 +53,6 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)      size_t start = 0;      size_t end = 0; -    char *tmp = NULL; -      unsigned int if_count = 0;      b_slist_t *stmts = NULL; @@ -340,6 +338,15 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)          current++;      } +    if (*err == NULL) { +        if (if_count != 0) +            *err = blogc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER, +                "%d 'if' statements were not closed!", if_count); +        else if (block_state != BLOCK_CLOSED) +            *err = blogc_error_new(BLOGC_ERROR_TEMPLATE_PARSER, +                "A block was not closed!"); +    } +      if (*err != NULL) {          if (stmt != NULL) {              free(stmt->value); | 
