aboutsummaryrefslogtreecommitdiffstats
path: root/src/template-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/template-parser.c')
-rw-r--r--src/template-parser.c63
1 files changed, 41 insertions, 22 deletions
diff --git a/src/template-parser.c b/src/template-parser.c
index 751fd9e..7e9a444 100644
--- a/src/template-parser.c
+++ b/src/template-parser.c
@@ -44,14 +44,6 @@ typedef enum {
} blogc_template_parser_state_t;
-typedef enum {
- BLOCK_CLOSED = 1,
- BLOCK_ENTRY,
- BLOCK_LISTING,
- BLOCK_LISTING_ONCE,
-} blogc_template_parser_block_state_t;
-
-
sb_slist_t*
blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
{
@@ -69,8 +61,10 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
blogc_template_stmt_operator_t tmp_op = 0;
unsigned int if_count = 0;
+ unsigned int block_if_count = 0;
bool else_open = false;
bool foreach_open = false;
+ bool block_foreach_open = false;
sb_slist_t *stmts = NULL;
blogc_template_stmt_t *stmt = NULL;
@@ -88,11 +82,13 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
bool lstrip_next = false;
char *tmp = NULL;
+ char *block_type = NULL;
blogc_template_parser_state_t state = TEMPLATE_START;
- blogc_template_parser_block_state_t block_state = BLOCK_CLOSED;
blogc_template_stmt_type_t type = BLOGC_TEMPLATE_CONTENT_STMT;
+ bool block_open = false;
+
while (current < src_len) {
char c = src[current];
bool last = current == src_len - 1;
@@ -194,10 +190,12 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
if ((current - start == 5) &&
(0 == strncmp("block", src + start, 5)))
{
- if (block_state == BLOCK_CLOSED) {
+ if (!block_open) {
state = TEMPLATE_BLOCK_BLOCK_TYPE_START;
type = BLOGC_TEMPLATE_BLOCK_STMT;
start = current;
+ block_if_count = if_count;
+ block_foreach_open = foreach_open;
break;
}
*err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
@@ -207,10 +205,23 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
else if ((current - start == 8) &&
(0 == strncmp("endblock", src + start, 8)))
{
- if (block_state != BLOCK_CLOSED) {
+ if (block_open) {
+ if (if_count != block_if_count) {
+ *err = blogc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER,
+ "%d open 'if', 'ifdef' and/or 'ifndef' statements "
+ "were not closed inside a '%s' block!",
+ if_count - block_if_count, block_type);
+ break;
+ }
+ if (!block_foreach_open && foreach_open) {
+ *err = blogc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER,
+ "An open 'foreach' statement was not closed "
+ "inside a '%s' block!", block_type);
+ break;
+ }
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
type = BLOGC_TEMPLATE_ENDBLOCK_STMT;
- block_state = BLOCK_CLOSED;
+ block_open = false;
break;
}
*err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,
@@ -251,7 +262,9 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
else if ((current - start == 4) &&
(0 == strncmp("else", src + start, 4)))
{
- if (if_count > 0) {
+ if ((block_open && if_count > block_if_count) ||
+ (!block_open && if_count > 0))
+ {
if (!else_open) {
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
type = BLOGC_TEMPLATE_ELSE_STMT;
@@ -273,7 +286,9 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
else if ((current - start == 5) &&
(0 == strncmp("endif", src + start, 5)))
{
- if (if_count > 0) {
+ if ((block_open && if_count > block_if_count) ||
+ (!block_open && if_count > 0))
+ {
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
type = BLOGC_TEMPLATE_ENDIF_STMT;
if_count--;
@@ -304,7 +319,9 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
else if ((current - start == 10) &&
(0 == strncmp("endforeach", src + start, 10)))
{
- if (foreach_open) {
+ if ((block_open && !block_foreach_open && foreach_open) ||
+ (!block_open && foreach_open))
+ {
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
type = BLOGC_TEMPLATE_ENDFOREACH_STMT;
foreach_open = false;
@@ -320,8 +337,8 @@ 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,
"Invalid statement type: Allowed types are: 'block', "
- "'endblock', 'ifdef', 'ifndef', 'else', 'endif', 'foreach' "
- "and 'endforeach'.");
+ "'endblock', 'if', 'ifdef', 'ifndef', 'else', 'endif', "
+ "'foreach' and 'endforeach'.");
break;
case TEMPLATE_BLOCK_BLOCK_TYPE_START:
@@ -344,7 +361,7 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
if ((current - start == 5) &&
(0 == strncmp("entry", src + start, 5)))
{
- block_state = BLOCK_ENTRY;
+ block_open = true;
end = current;
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
break;
@@ -352,7 +369,7 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
else if ((current - start == 7) &&
(0 == strncmp("listing", src + start, 7)))
{
- block_state = BLOCK_LISTING;
+ block_open = true;
end = current;
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
break;
@@ -360,7 +377,7 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
else if ((current - start == 12) &&
(0 == strncmp("listing_once", src + start, 12)))
{
- block_state = BLOCK_LISTING_ONCE;
+ block_open = true;
end = current;
state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
break;
@@ -598,6 +615,8 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
start2 = 0;
end2 = 0;
}
+ if (type == BLOGC_TEMPLATE_BLOCK_STMT)
+ block_type = stmt->value;
stmts = sb_slist_append(stmts, stmt);
previous = stmt;
stmt = NULL;
@@ -625,9 +644,9 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)
start2, "Found an open double-quoted string.");
else if (if_count != 0)
*err = blogc_error_new_printf(BLOGC_ERROR_TEMPLATE_PARSER,
- "%d open 'ifdef' and/or 'ifndef' statements were not closed!",
+ "%d open 'if', 'ifdef' and/or 'ifndef' statements were not closed!",
if_count);
- else if (block_state != BLOCK_CLOSED)
+ else if (block_open)
*err = blogc_error_new(BLOGC_ERROR_TEMPLATE_PARSER,
"An open block was not closed!");
else if (foreach_open)