diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/debug.c | 3 | ||||
| -rw-r--r-- | src/renderer.c | 49 | ||||
| -rw-r--r-- | src/template-parser.c | 31 | ||||
| -rw-r--r-- | src/template-parser.h | 1 | 
4 files changed, 80 insertions, 4 deletions
| diff --git a/src/debug.c b/src/debug.c index 767e1a5..7039608 100644 --- a/src/debug.c +++ b/src/debug.c @@ -55,6 +55,9 @@ blogc_debug_template(sb_slist_t *stmts)                  fprintf(stderr, "IF: %s %s %s", data->value,                      get_operator(data->op), data->value2);                  break; +            case BLOGC_TEMPLATE_ELSE_STMT: +                fprintf(stderr, "ELSE"); +                break;              case BLOGC_TEMPLATE_ENDIF_STMT:                  fprintf(stderr, "ENDIF");                  break; diff --git a/src/renderer.c b/src/renderer.c index 0f71ba7..351dfb1 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -188,6 +188,7 @@ blogc_render(sb_slist_t *tmpl, sb_slist_t *sources, sb_trie_t *config, bool list      bool if_not = false;      bool inside_block = false;      bool evaluate = false; +    bool valid_else = false;      int cmp = 0; @@ -343,13 +344,23 @@ blogc_render(sb_slist_t *tmpl, sb_slist_t *sources, sb_trie_t *config, bool list                              if_count++;                              continue;                          } +                        if ((stmt->type == BLOGC_TEMPLATE_ELSE_STMT) && +                            (if_count == 0)) +                        { +                            // this is somewhat complex. only an else statement +                            // right after a non evaluated block should be considered +                            // valid, because all the inner conditionals were just +                            // skipped, and all the outter conditionals evaluated +                            // to true. +                            valid_else = true; +                            break; +                        }                          if (stmt->type == BLOGC_TEMPLATE_ENDIF_STMT) {                              if (if_count > 0) {                                  if_count--;                                  continue;                              } -                            if (if_count == 0) -                                break; +                            break;                          }                      }                  } @@ -358,7 +369,41 @@ blogc_render(sb_slist_t *tmpl, sb_slist_t *sources, sb_trie_t *config, bool list                  if_not = false;                  break; +            case BLOGC_TEMPLATE_ELSE_STMT: +                if_count = 0; +                if (!valid_else) { + +                    // 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) || +                            (stmt->type == BLOGC_TEMPLATE_IFDEF_STMT) || +                            (stmt->type == BLOGC_TEMPLATE_IFNDEF_STMT)) +                        { +                            if_count++; +                            continue; +                        } +                        // no need to handle else statements here, because every +                        // if should have an endif. +                        if (stmt->type == BLOGC_TEMPLATE_ENDIF_STMT) { +                            if (if_count > 0) { +                                if_count--; +                                continue; +                            } +                            break; +                        } +                    } +                } +                valid_else = false; +                break; +              case BLOGC_TEMPLATE_ENDIF_STMT: +                // any endif statement should invalidate valid_else, to avoid +                // propagation to outter conditionals. +                valid_else = false;                  if (if_count > 0)                      if_count--;                  break; diff --git a/src/template-parser.c b/src/template-parser.c index 525f5f5..344e398 100644 --- a/src/template-parser.c +++ b/src/template-parser.c @@ -69,6 +69,7 @@ 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; +    bool else_open = false;      bool foreach_open = false;      sb_slist_t *stmts = NULL; @@ -224,6 +225,7 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)                          type = BLOGC_TEMPLATE_IFDEF_STMT;                          start = current;                          if_count++; +                        else_open = false;                          break;                      }                      else if ((current - start == 6) && @@ -233,6 +235,7 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)                          type = BLOGC_TEMPLATE_IFNDEF_STMT;                          start = current;                          if_count++; +                        else_open = false;                          break;                      }                      else if ((current - start == 2) && @@ -242,6 +245,29 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)                          type = BLOGC_TEMPLATE_IF_STMT;                          start = current;                          if_count++; +                        else_open = false; +                        break; +                    } +                    else if ((current - start == 4) && +                        (0 == strncmp("else", src + start, 4))) +                    { +                        if (if_count > 0) { +                            if (!else_open) { +                                state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER; +                                type = BLOGC_TEMPLATE_ELSE_STMT; +                                else_open = true; +                                break; +                            } +                            *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, +                                src, src_len, current, +                                "More than one 'else' statement for an open 'if', " +                                "'ifdef' or 'ifndef' statement."); +                            break; +                        } +                        *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, +                            src, src_len, current, +                            "'else' statement without an open 'if', 'ifdef' or " +                            "'ifndef' statement.");                          break;                      }                      else if ((current - start == 5) && @@ -251,12 +277,13 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)                              state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;                              type = BLOGC_TEMPLATE_ENDIF_STMT;                              if_count--; +                            else_open = false;                              break;                          }                          *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,                              src, src_len, current, -                            "'endif' statement without an open 'ifdef' or 'ifndef' " -                            "statement."); +                            "'endif' statement without an open 'if', 'ifdef' or " +                            "'ifndef' statement.");                          break;                      }                      else if ((current - start == 7) && diff --git a/src/template-parser.h b/src/template-parser.h index 46223ec..fe2721e 100644 --- a/src/template-parser.h +++ b/src/template-parser.h @@ -21,6 +21,7 @@ typedef enum {      BLOGC_TEMPLATE_IFDEF_STMT = 1,      BLOGC_TEMPLATE_IFNDEF_STMT,      BLOGC_TEMPLATE_IF_STMT, +    BLOGC_TEMPLATE_ELSE_STMT,      BLOGC_TEMPLATE_ENDIF_STMT,      BLOGC_TEMPLATE_FOREACH_STMT,      BLOGC_TEMPLATE_ENDFOREACH_STMT, | 
