diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/template-parser.c | 63 | 
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)  | 
