diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/renderer.c | 14 | ||||
-rw-r--r-- | src/template-parser.c | 34 | ||||
-rw-r--r-- | src/template-parser.h | 1 |
3 files changed, 44 insertions, 5 deletions
diff --git a/src/renderer.c b/src/renderer.c index 69206c3..92fa7d4 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -34,6 +34,8 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing) unsigned int if_count = 0; unsigned int if_skip = 0; + bool if_not = false; + b_slist_t *tmp = tmpl; while (tmp != NULL) { blogc_template_stmt_t *stmt = tmp->data; @@ -104,9 +106,14 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing) } break; + case BLOGC_TEMPLATE_IF_NOT_STMT: + if_not = true; + case BLOGC_TEMPLATE_IF_STMT: if (stmt->value != NULL && tmp_source != NULL) { - if (b_trie_lookup(tmp_source, stmt->value) == NULL) { + if ((!if_not && (b_trie_lookup(tmp_source, stmt->value) == NULL)) || + (if_not && (b_trie_lookup(tmp_source, stmt->value) != NULL))) + { if_skip = if_count; // at this point we can just skip anything, counting the @@ -115,7 +122,9 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing) while (1) { tmp = tmp->next; stmt = tmp->data; - if (stmt->type == BLOGC_TEMPLATE_IF_STMT) { + if ((stmt->type == BLOGC_TEMPLATE_IF_STMT) || + (stmt->type == BLOGC_TEMPLATE_IF_NOT_STMT)) + { if_count++; continue; } @@ -129,6 +138,7 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing) } } } + if_not = false; } break; diff --git a/src/template-parser.c b/src/template-parser.c index 319ae4b..0fcf898 100644 --- a/src/template-parser.c +++ b/src/template-parser.c @@ -25,7 +25,8 @@ typedef enum { TEMPLATE_BLOCK_TYPE, TEMPLATE_BLOCK_BLOCK_TYPE_START, TEMPLATE_BLOCK_BLOCK_TYPE, - TEMPLATE_BLOCK_IF_VARIABLE_START, + TEMPLATE_BLOCK_IF_START, + TEMPLATE_BLOCK_IF_CONDITION, TEMPLATE_BLOCK_IF_VARIABLE, TEMPLATE_BLOCK_END, TEMPLATE_VARIABLE_START, @@ -54,6 +55,7 @@ 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,7 +144,7 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err) } else if (0 == strncmp("if", src + start, current - start)) { if (block_state == BLOCK_ENTRY || block_state == BLOCK_LISTING) { - state = TEMPLATE_BLOCK_IF_VARIABLE_START; + state = TEMPLATE_BLOCK_IF_START; type = BLOGC_TEMPLATE_IF_STMT; start = current; if_count++; @@ -222,9 +224,17 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err) "and 'listing_once'."); break; - case TEMPLATE_BLOCK_IF_VARIABLE_START: + case TEMPLATE_BLOCK_IF_START: if (c == ' ') break; + if (c >= 'a' && c <= 'z') { + if (!conditional) { + conditional = true; + state = TEMPLATE_BLOCK_IF_CONDITION; + start = current; + break; + } + } if (c >= 'A' && c <= 'Z') { state = TEMPLATE_BLOCK_IF_VARIABLE; start = current; @@ -235,6 +245,23 @@ 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)) { + block_state = BLOCK_ENTRY; + 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: if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_') break; @@ -253,6 +280,7 @@ 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; } diff --git a/src/template-parser.h b/src/template-parser.h index d95c87a..8fe3630 100644 --- a/src/template-parser.h +++ b/src/template-parser.h @@ -14,6 +14,7 @@ typedef enum { BLOGC_TEMPLATE_IF_STMT = 1, + BLOGC_TEMPLATE_IF_NOT_STMT, BLOGC_TEMPLATE_ENDIF_STMT, BLOGC_TEMPLATE_BLOCK_STMT, BLOGC_TEMPLATE_ENDBLOCK_STMT, |