From dbfd651c575c17f8b891bd789a60d11ca954751e Mon Sep 17 00:00:00 2001 From: "Rafael G. Martins" Date: Sun, 17 May 2015 01:30:35 -0300 Subject: template-parser: if -> ifdef, if not -> ifndef --- README.md | 2 +- src/renderer.c | 8 +++--- src/template-parser.c | 58 +++++++++++++------------------------ src/template-parser.h | 4 +-- tests/check_renderer.c | 56 ++++++++++++++++++------------------ tests/check_template_parser.c | 66 ++++++++++++++++--------------------------- 6 files changed, 80 insertions(+), 114 deletions(-) diff --git a/README.md b/README.md index 89b8b35..81809dc 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ The templates can define blocks. These are the block rules: The variables defined in source files are only available inside of blocks. The variables defined in the command line are global and available everywhere. Inside blocks, variables defined in source files are always used, even if a global variable with the same name exists. -The templates can use conditional statements: ``{% if VARIABLE %}`` or ``{% if not VARIABLE %}``, and ``{% endif %}``. They check if a variable is defined or not. +The templates can use conditional statements: ``{% ifdef VARIABLE %}`` or ``{% ifndef VARIABLE %}``, and ``{% endif %}``. They check if a variable is defined or not. Variables defined in source files are not available in ``listing_once`` blocks, because it is not possible to guess which source file would provide the variable contents. Global variables, defined in the command line are available. diff --git a/src/renderer.c b/src/renderer.c index c73244b..7a2fb77 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -184,10 +184,10 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources, b_trie_t *config, bool listing } break; - case BLOGC_TEMPLATE_IF_NOT_STMT: + case BLOGC_TEMPLATE_IFNDEF_STMT: if_not = true; - case BLOGC_TEMPLATE_IF_STMT: + case BLOGC_TEMPLATE_IFDEF_STMT: defined = false; if (stmt->value != NULL) { config_var = NULL; @@ -221,8 +221,8 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources, b_trie_t *config, bool listing while (1) { tmp = tmp->next; stmt = tmp->data; - if ((stmt->type == BLOGC_TEMPLATE_IF_STMT) || - (stmt->type == BLOGC_TEMPLATE_IF_NOT_STMT)) + if ((stmt->type == BLOGC_TEMPLATE_IFDEF_STMT) || + (stmt->type == BLOGC_TEMPLATE_IFNDEF_STMT)) { if_count++; continue; diff --git a/src/template-parser.c b/src/template-parser.c index 42fc5e2..d25ea0f 100644 --- a/src/template-parser.c +++ b/src/template-parser.c @@ -25,9 +25,8 @@ typedef enum { TEMPLATE_BLOCK_TYPE, TEMPLATE_BLOCK_BLOCK_TYPE_START, TEMPLATE_BLOCK_BLOCK_TYPE, - TEMPLATE_BLOCK_IF_START, - TEMPLATE_BLOCK_IF_CONDITION, - TEMPLATE_BLOCK_IF_VARIABLE, + TEMPLATE_BLOCK_IFDEF_START, + TEMPLATE_BLOCK_IFDEF_VARIABLE, TEMPLATE_BLOCK_END, TEMPLATE_VARIABLE_START, TEMPLATE_VARIABLE, @@ -55,7 +54,6 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err) size_t end = 0; unsigned int if_count = 0; - bool conditional = false; b_slist_t *stmts = NULL; blogc_template_stmt_t *stmt = NULL; @@ -142,9 +140,16 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err) "'endblock' statement without an open 'block' statement."); break; } - else if (0 == strncmp("if", src + start, current - start)) { - state = TEMPLATE_BLOCK_IF_START; - type = BLOGC_TEMPLATE_IF_STMT; + else if (0 == strncmp("ifdef", src + start, current - start)) { + state = TEMPLATE_BLOCK_IFDEF_START; + type = BLOGC_TEMPLATE_IFDEF_STMT; + start = current; + if_count++; + break; + } + else if (0 == strncmp("ifndef", src + start, current - start)) { + state = TEMPLATE_BLOCK_IFDEF_START; + type = BLOGC_TEMPLATE_IFNDEF_STMT; start = current; if_count++; break; @@ -158,14 +163,15 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err) } *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src, src_len, current, - "'endif' statement without an open 'if' statement."); + "'endif' statement without an open 'ifdef' or 'ifndef' " + "statement."); break; } } *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src, src_len, current, "Invalid statement type: Allowed types are: 'block', " - "'endblock', 'if' and 'endif'."); + "'endblock', 'ifdef', 'ifndef' and 'endif'."); break; case TEMPLATE_BLOCK_BLOCK_TYPE_START: @@ -210,19 +216,11 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err) "and 'listing_once'."); break; - case TEMPLATE_BLOCK_IF_START: + case TEMPLATE_BLOCK_IFDEF_START: if (c == ' ') break; - if (c == 'n') { - if (!conditional) { - conditional = true; - state = TEMPLATE_BLOCK_IF_CONDITION; - start = current; - break; - } - } if (c >= 'A' && c <= 'Z') { - state = TEMPLATE_BLOCK_IF_VARIABLE; + state = TEMPLATE_BLOCK_IFDEF_VARIABLE; start = current; break; } @@ -231,23 +229,7 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err) "Invalid variable name. Must begin with uppercase letter."); break; - case TEMPLATE_BLOCK_IF_CONDITION: - if (c >= 'a' && c <= 'z') - break; - if (c == ' ') { - if (0 == strncmp("not", src + start, current - start)) { - end = current; - state = TEMPLATE_BLOCK_IF_START; - type = BLOGC_TEMPLATE_IF_NOT_STMT; - break; - } - } - *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src, - src_len, current, - "Invalid 'if' condition. Allowed conditions are: 'not'."); - break; - - case TEMPLATE_BLOCK_IF_VARIABLE: + case TEMPLATE_BLOCK_IFDEF_VARIABLE: if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_') break; if (c == ' ') { @@ -265,7 +247,6 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err) if (c == ' ') break; if (c == '%') { - conditional = false; state = TEMPLATE_CLOSE_BRACKET; break; } @@ -349,7 +330,8 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err) if (*err == NULL) { if (if_count != 0) *err = blogc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER, - "%d open 'if' statements were not closed!", if_count); + "%d open 'ifdef' and/or 'ifndef' statements were not closed!", + if_count); else if (block_state != BLOCK_CLOSED) *err = blogc_error_new(BLOGC_ERROR_TEMPLATE_PARSER, "An open block was not closed!"); diff --git a/src/template-parser.h b/src/template-parser.h index 8fe3630..88c9ccf 100644 --- a/src/template-parser.h +++ b/src/template-parser.h @@ -13,8 +13,8 @@ #include "error.h" typedef enum { - BLOGC_TEMPLATE_IF_STMT = 1, - BLOGC_TEMPLATE_IF_NOT_STMT, + BLOGC_TEMPLATE_IFDEF_STMT = 1, + BLOGC_TEMPLATE_IFNDEF_STMT, BLOGC_TEMPLATE_ENDIF_STMT, BLOGC_TEMPLATE_BLOCK_STMT, BLOGC_TEMPLATE_ENDBLOCK_STMT, diff --git a/tests/check_renderer.c b/tests/check_renderer.c index 4c77057..0244e30 100644 --- a/tests/check_renderer.c +++ b/tests/check_renderer.c @@ -133,13 +133,13 @@ test_render_listing(void **state) static void -test_render_if(void **state) +test_render_ifdef(void **state) { const char *str = "{% block entry %}\n" - "{% if CHUNDA %}chunda\n" - "{% if GUDA %}guda\n" - "{% if BOLA %}bola\n" + "{% ifdef CHUNDA %}chunda\n" + "{% ifdef GUDA %}guda\n" + "{% ifdef BOLA %}bola\n" "{% endif %}\n" "{% endif %}\n" "{% endif %}\n" @@ -162,13 +162,13 @@ test_render_if(void **state) static void -test_render_if2(void **state) +test_render_ifdef2(void **state) { const char *str = "{% block entry %}\n" - "{% if GUDA %}guda\n" - "{% if CHUNDA %}chunda\n" - "{% if BOLA %}bola\n" + "{% ifdef GUDA %}guda\n" + "{% ifdef CHUNDA %}chunda\n" + "{% ifdef BOLA %}bola\n" "{% endif %}\n" "{% endif %}\n" "{% endif %}\n" @@ -193,13 +193,13 @@ test_render_if2(void **state) static void -test_render_if3(void **state) +test_render_ifdef3(void **state) { const char *str = "{% block entry %}\n" - "{% if GUDA %}guda\n" - "{% if BOLA %}bola\n" - "{% if CHUNDA %}chunda\n" + "{% ifdef GUDA %}guda\n" + "{% ifdef BOLA %}bola\n" + "{% ifdef CHUNDA %}chunda\n" "{% endif %}\n" "{% endif %}\n" "{% endif %}\n" @@ -226,13 +226,13 @@ test_render_if3(void **state) static void -test_render_if_not(void **state) +test_render_ifndef(void **state) { const char *str = "{% block entry %}\n" - "{% if not CHUNDA %}chunda\n" - "{% if GUDA %}guda\n" - "{% if not BOLA %}bola\n" + "{% ifndef CHUNDA %}chunda\n" + "{% ifdef GUDA %}guda\n" + "{% ifndef BOLA %}bola\n" "{% endif %}\n" "{% endif %}\n" "{% endif %}\n" @@ -269,9 +269,9 @@ static void test_render_outside_block(void **state) { const char *str = - "{% if GUDA %}bola{% endif %}\n" + "{% ifdef GUDA %}bola{% endif %}\n" "{{ BOLA }}\n" - "{% if not CHUNDA %}lol{% endif %}\n"; + "{% ifndef CHUNDA %}lol{% endif %}\n"; blogc_error_t *err = NULL; b_slist_t *l = blogc_template_parse(str, strlen(str), &err); assert_non_null(l); @@ -297,10 +297,10 @@ test_render_prefer_local_variable(void **state) { const char *str = "{% block entry %}\n" - "{% if LOL %}{{ LOL }}{% endif %}\n" - "{% if not CHUNDA %}chunda\n" - "{% if GUDA %}{{ GUDA }}\n" - "{% if not BOLA %}bola\n" + "{% ifdef LOL %}{{ LOL }}{% endif %}\n" + "{% ifndef CHUNDA %}chunda\n" + "{% ifdef GUDA %}{{ GUDA }}\n" + "{% ifndef BOLA %}bola\n" "{% endif %}\n" "{% endif %}\n" "{% endif %}\n" @@ -338,8 +338,8 @@ test_render_respect_variable_scope(void **state) "{{ LOL }}\n" "{{ BOLA }}\n" "{% block entry %}\n" - "{% if LOL %}{{ LOL }}{% endif %}\n" - "{% if BOLA %}{{ BOLA }}{% endif %}\n" + "{% ifdef LOL %}{{ LOL }}{% endif %}\n" + "{% ifdef BOLA %}{{ BOLA }}{% endif %}\n" "{% endblock %}\n"; blogc_error_t *err = NULL; b_slist_t *l = blogc_template_parse(str, strlen(str), &err); @@ -469,10 +469,10 @@ main(void) const UnitTest tests[] = { unit_test(test_render_entry), unit_test(test_render_listing), - unit_test(test_render_if), - unit_test(test_render_if2), - unit_test(test_render_if3), - unit_test(test_render_if_not), + unit_test(test_render_ifdef), + unit_test(test_render_ifdef2), + unit_test(test_render_ifdef3), + unit_test(test_render_ifndef), unit_test(test_render_outside_block), unit_test(test_render_null), unit_test(test_render_prefer_local_variable), diff --git a/tests/check_template_parser.c b/tests/check_template_parser.c index bbef763..3479ca5 100644 --- a/tests/check_template_parser.c +++ b/tests/check_template_parser.c @@ -40,10 +40,10 @@ test_template_parse(void **state) "Test\n" "\n" " {% block entry %}\n" - "{% if CHUNDA %}\n" + "{% ifdef CHUNDA %}\n" "bola\n" "{% endif %}\n" - "{% if not BOLA %}\n" + "{% ifndef BOLA %}\n" "bolao\n" "{% endif %}\n" "{% endblock %}\n" @@ -60,7 +60,7 @@ test_template_parse(void **state) blogc_assert_template_stmt(stmts->next->next, "\n", BLOGC_TEMPLATE_CONTENT_STMT); blogc_assert_template_stmt(stmts->next->next->next, "CHUNDA", - BLOGC_TEMPLATE_IF_STMT); + BLOGC_TEMPLATE_IFDEF_STMT); blogc_assert_template_stmt(stmts->next->next->next->next, "\nbola\n", BLOGC_TEMPLATE_CONTENT_STMT); blogc_assert_template_stmt(stmts->next->next->next->next->next, NULL, @@ -68,7 +68,7 @@ test_template_parse(void **state) blogc_assert_template_stmt(stmts->next->next->next->next->next->next, "\n", BLOGC_TEMPLATE_CONTENT_STMT); b_slist_t *tmp = stmts->next->next->next->next->next->next->next; - blogc_assert_template_stmt(tmp, "BOLA", BLOGC_TEMPLATE_IF_NOT_STMT); + blogc_assert_template_stmt(tmp, "BOLA", BLOGC_TEMPLATE_IFNDEF_STMT); blogc_assert_template_stmt(tmp->next, "\nbolao\n", BLOGC_TEMPLATE_CONTENT_STMT); blogc_assert_template_stmt(tmp->next->next, NULL, BLOGC_TEMPLATE_ENDIF_STMT); blogc_assert_template_stmt(tmp->next->next->next, "\n", @@ -114,12 +114,12 @@ test_template_parse_html(void **state) "

My cool blog

\n" " {% block entry %}\n" "

{{ TITLE }}

\n" - " {% if DATE %}

Published in: {{ DATE }}

{% endif %}\n" + " {% ifdef DATE %}

Published in: {{ DATE }}

{% endif %}\n" "
{{ CONTENT }}
\n" " {% endblock %}\n" " {% block listing_once %}{% endblock %}\n" " \n" "\n"; @@ -160,7 +160,7 @@ test_template_parse_html(void **state) blogc_assert_template_stmt(tmp->next->next->next->next->next->next, "\n ", BLOGC_TEMPLATE_CONTENT_STMT); blogc_assert_template_stmt(tmp->next->next->next->next->next->next->next, - "DATE", BLOGC_TEMPLATE_IF_STMT); + "DATE", BLOGC_TEMPLATE_IFDEF_STMT); tmp = tmp->next->next->next->next->next->next->next->next; blogc_assert_template_stmt(tmp, "

Published in: ", BLOGC_TEMPLATE_CONTENT_STMT); @@ -200,7 +200,7 @@ test_template_parse_html(void **state) blogc_assert_template_stmt(tmp->next->next, "", BLOGC_TEMPLATE_CONTENT_STMT); blogc_assert_template_stmt(tmp->next->next->next, "DATE", - BLOGC_TEMPLATE_IF_STMT); + BLOGC_TEMPLATE_IFDEF_STMT); blogc_assert_template_stmt(tmp->next->next->next->next, " - ", BLOGC_TEMPLATE_CONTENT_STMT); blogc_assert_template_stmt(tmp->next->next->next->next->next, "DATE", @@ -227,17 +227,17 @@ test_template_parse_html(void **state) static void -test_template_parse_if_and_var_outside_block(void **state) +test_template_parse_ifdef_and_var_outside_block(void **state) { const char *a = - "{% if GUDA %}bola{% endif %}\n" + "{% ifdef GUDA %}bola{% endif %}\n" "{{ BOLA }}\n" - "{% if not CHUNDA %}{{ CHUNDA }}{% endif %}\n"; + "{% ifndef CHUNDA %}{{ CHUNDA }}{% endif %}\n"; blogc_error_t *err = NULL; b_slist_t *stmts = blogc_template_parse(a, strlen(a), &err); assert_null(err); assert_non_null(stmts); - blogc_assert_template_stmt(stmts, "GUDA", BLOGC_TEMPLATE_IF_STMT); + blogc_assert_template_stmt(stmts, "GUDA", BLOGC_TEMPLATE_IFDEF_STMT); blogc_assert_template_stmt(stmts->next, "bola", BLOGC_TEMPLATE_CONTENT_STMT); blogc_assert_template_stmt(stmts->next->next, NULL, @@ -249,7 +249,7 @@ test_template_parse_if_and_var_outside_block(void **state) blogc_assert_template_stmt(stmts->next->next->next->next->next, "\n", BLOGC_TEMPLATE_CONTENT_STMT); blogc_assert_template_stmt(stmts->next->next->next->next->next->next, - "CHUNDA", BLOGC_TEMPLATE_IF_NOT_STMT); + "CHUNDA", BLOGC_TEMPLATE_IFNDEF_STMT); b_slist_t *tmp = stmts->next->next->next->next->next->next->next; blogc_assert_template_stmt(tmp, "CHUNDA", BLOGC_TEMPLATE_VARIABLE_STMT); blogc_assert_template_stmt(tmp->next, NULL, BLOGC_TEMPLATE_ENDIF_STMT); @@ -320,7 +320,7 @@ test_template_parse_invalid_endif_not_open(void **state) assert_null(stmts); assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER); assert_string_equal(err->msg, - "'endif' statement without an open 'if' statement.\n" + "'endif' statement without an open 'ifdef' or 'ifndef' statement.\n" "Error occurred near to ' %}{% endblock %}'"); blogc_error_free(err); } @@ -336,8 +336,8 @@ test_template_parse_invalid_block_name(void **state) assert_null(stmts); assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER); assert_string_equal(err->msg, - "Invalid statement type: Allowed types are: 'block', 'endblock', 'if' and 'endif'.\n" - "Error occurred near to ' %}'"); + "Invalid statement type: Allowed types are: 'block', 'endblock', 'ifdef', " + "'ifndef' and 'endif'.\nError occurred near to ' %}'"); blogc_error_free(err); } @@ -375,9 +375,9 @@ test_template_parse_invalid_block_type(void **state) static void -test_template_parse_invalid_if_start(void **state) +test_template_parse_invalid_ifdef_start(void **state) { - const char *a = "{% block entry %}{% if guda %}\n"; + const char *a = "{% block entry %}{% ifdef guda %}\n"; blogc_error_t *err = NULL; b_slist_t *stmts = blogc_template_parse(a, strlen(a), &err); assert_non_null(err); @@ -391,25 +391,9 @@ test_template_parse_invalid_if_start(void **state) static void -test_template_parse_invalid_if_condition(void **state) -{ - const char *a = "{% block entry %}{% if non BOLA %}\n"; - blogc_error_t *err = NULL; - b_slist_t *stmts = blogc_template_parse(a, strlen(a), &err); - assert_non_null(err); - assert_null(stmts); - assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER); - assert_string_equal(err->msg, - "Invalid 'if' condition. Allowed conditions are: 'not'.\n" - "Error occurred near to ' BOLA %}'"); - blogc_error_free(err); -} - - -static void -test_template_parse_invalid_if_variable(void **state) +test_template_parse_invalid_ifdef_variable(void **state) { - const char *a = "{% block entry %}{% if BoLA %}\n"; + const char *a = "{% block entry %}{% ifdef BoLA %}\n"; blogc_error_t *err = NULL; b_slist_t *stmts = blogc_template_parse(a, strlen(a), &err); assert_non_null(err); @@ -527,7 +511,8 @@ test_template_parse_invalid_if_not_closed(void **state) assert_non_null(err); assert_null(stmts); assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER); - assert_string_equal(err->msg, "1 open 'if' statements were not closed!"); + assert_string_equal(err->msg, "1 open 'ifdef' and/or 'ifndef' statements " + "were not closed!"); blogc_error_free(err); } @@ -552,7 +537,7 @@ main(void) const UnitTest tests[] = { unit_test(test_template_parse), unit_test(test_template_parse_html), - unit_test(test_template_parse_if_and_var_outside_block), + unit_test(test_template_parse_ifdef_and_var_outside_block), unit_test(test_template_parse_invalid_block_start), unit_test(test_template_parse_invalid_block_nested), unit_test(test_template_parse_invalid_block_not_open), @@ -560,9 +545,8 @@ main(void) unit_test(test_template_parse_invalid_block_name), unit_test(test_template_parse_invalid_block_type_start), unit_test(test_template_parse_invalid_block_type), - unit_test(test_template_parse_invalid_if_start), - unit_test(test_template_parse_invalid_if_condition), - unit_test(test_template_parse_invalid_if_variable), + unit_test(test_template_parse_invalid_ifdef_start), + unit_test(test_template_parse_invalid_ifdef_variable), unit_test(test_template_parse_invalid_block_end), unit_test(test_template_parse_invalid_variable_name), unit_test(test_template_parse_invalid_variable_name2), -- cgit v1.2.3-18-g5258