diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 26 | ||||
| -rw-r--r-- | src/renderer.c | 26 | ||||
| -rw-r--r-- | src/renderer.h | 3 | ||||
| -rw-r--r-- | src/template-parser.c | 54 | 
4 files changed, 64 insertions, 45 deletions
| @@ -36,13 +36,14 @@ blogc_print_help(void)  {      printf(          "usage:\n" -        "    blogc [-h] -t TEMPLATE [-o OUTPUT] SOURCE [SOURCE ...] - A blog compiler.\n" +        "    blogc [-h] [-l] -t TEMPLATE [-o OUTPUT] SOURCE [SOURCE ...] - A blog compiler.\n"          "\n"          "positional arguments:\n"          "    SOURCE       source file(s)\n"          "\n"          "optional arguments:\n" -        "    -h, --help   show this help message and exit\n" +        "    -h           show this help message and exit\n" +        "    -l           build listing page, from multiple source files\n"          "    -t TEMPLATE  template file\n"          "    -o OUTPUT    output file\n");  } @@ -51,7 +52,7 @@ blogc_print_help(void)  static void  blogc_print_usage(void)  { -    printf("usage: blogc [-h] -t TEMPLATE [-o OUTPUT] SOURCE [SOURCE ...]\n"); +    printf("usage: blogc [-h] [-l] -t TEMPLATE [-o OUTPUT] SOURCE [SOURCE ...]\n");  } @@ -95,6 +96,7 @@ main(int argc, char **argv)  {      int rv = 0; +    bool listing = false;      char *template = NULL;      char *output = NULL;      b_slist_t *sources = NULL; @@ -105,6 +107,9 @@ main(int argc, char **argv)                  case 'h':                      blogc_print_help();                      goto cleanup; +                case 'l': +                    listing = true; +                    break;                  case 't':                      if (i + 1 < argc)                          template = b_strdup(argv[++i]); @@ -128,7 +133,18 @@ main(int argc, char **argv)      if (b_slist_length(sources) == 0) {          blogc_print_usage(); -        fprintf(stderr, "blogc: error: at least one source file is required\n"); +        if (listing) +            fprintf(stderr, "blogc: error: at least one source file is required\n"); +        else +            fprintf(stderr, "blogc: error: one source file is required\n"); +        rv = 2; +        goto cleanup; +    } + +    if (!listing && b_slist_length(sources) > 1) { +        blogc_print_usage(); +        fprintf(stderr, "blogc: error: only one source file should be provided, " +            "if running without '-l'\n");          rv = 2;          goto cleanup;      } @@ -147,7 +163,7 @@ main(int argc, char **argv)          goto cleanup3;      } -    char *out = blogc_render(l, s); +    char *out = blogc_render(l, s, listing);      bool write_to_stdout = (output == NULL || (0 == strcmp(output, "-"))); diff --git a/src/renderer.c b/src/renderer.c index ffd46c9..69206c3 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -18,15 +18,13 @@  char* -blogc_render(b_slist_t *tmpl, b_slist_t *sources) +blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing)  {      if (tmpl == NULL || sources == NULL)          return NULL; -    bool single_source = sources->next == NULL; -      b_slist_t *current_source = NULL; -    b_slist_t *multiple_sources_start = NULL; +    b_slist_t *listing_start = NULL;      b_string_t *str = b_string_new(); @@ -49,8 +47,8 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources)              case BLOGC_TEMPLATE_BLOCK_STMT:                  if_count = 0; -                if (0 == strcmp("single_source", stmt->value)) { -                    if (!single_source) { +                if (0 == strcmp("entry", stmt->value)) { +                    if (listing) {                          // we can just skip anything and walk until the next                          // 'endblock' @@ -63,9 +61,9 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources)                      current_source = sources;                      tmp_source = current_source->data;                  } -                else if ((0 == strcmp("multiple_sources", stmt->value)) || -                         (0 == strcmp("multiple_sources_once", stmt->value))) { -                    if (single_source) { +                else if ((0 == strcmp("listing", stmt->value)) || +                         (0 == strcmp("listing_once", stmt->value))) { +                    if (!listing) {                          // we can just skip anything and walk until the next                          // 'endblock' @@ -76,9 +74,9 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources)                          break;                      }                  } -                if (0 == strcmp("multiple_sources", stmt->value)) { +                if (0 == strcmp("listing", stmt->value)) {                      if (current_source == NULL) { -                        multiple_sources_start = tmp; +                        listing_start = tmp;                          current_source = sources;                      }                      tmp_source = current_source->data; @@ -95,14 +93,14 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources)                  break;              case BLOGC_TEMPLATE_ENDBLOCK_STMT: -                if (multiple_sources_start != NULL && current_source != NULL) { +                if (listing_start != NULL && current_source != NULL) {                      current_source = current_source->next;                      if (current_source != NULL) { -                        tmp = multiple_sources_start; +                        tmp = listing_start;                          continue;                      }                      else -                        multiple_sources_start = NULL; +                        listing_start = NULL;                  }                  break; diff --git a/src/renderer.h b/src/renderer.h index 9baf2eb..a6b7a2c 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -9,8 +9,9 @@  #ifndef _RENDERER_H  #define _RENDERER_H +#include <stdbool.h>  #include "utils/utils.h" -char* blogc_render(b_slist_t *tmpl, b_slist_t *sources); +char* blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing);  #endif /* _RENDERER_H */ diff --git a/src/template-parser.c b/src/template-parser.c index ce7dc32..319ae4b 100644 --- a/src/template-parser.c +++ b/src/template-parser.c @@ -37,9 +37,9 @@ typedef enum {  typedef enum {      BLOCK_CLOSED = 1, -    BLOCK_SINGLE_SOURCE, -    BLOCK_MULTIPLE_SOURCES, -    BLOCK_MULTIPLE_SOURCES_ONCE, +    BLOCK_ENTRY, +    BLOCK_LISTING, +    BLOCK_LISTING_ONCE,  } blogc_template_parser_block_state_t; @@ -110,7 +110,7 @@ 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 syntax. Must begin lowercase letter."); +                    "Invalid statement syntax. Must begin with lowercase letter.");                  break;              case TEMPLATE_BLOCK_TYPE: @@ -141,7 +141,7 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)                          break;                      }                      else if (0 == strncmp("if", src + start, current - start)) { -                        if (block_state == BLOCK_SINGLE_SOURCE || block_state == BLOCK_MULTIPLE_SOURCES) { +                        if (block_state == BLOCK_ENTRY || block_state == BLOCK_LISTING) {                              state = TEMPLATE_BLOCK_IF_VARIABLE_START;                              type = BLOGC_TEMPLATE_IF_STMT;                              start = current; @@ -150,12 +150,12 @@ 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, -                            "'if' statements only allowed inside 'single_source' " -                            "and 'multiple_sources' blocks."); +                            "'if' statements only allowed inside 'entry' and " +                            "'listing' blocks.");                          break;                      }                      else if (0 == strncmp("endif", src + start, current - start)) { -                        if (block_state == BLOCK_SINGLE_SOURCE || block_state == BLOCK_MULTIPLE_SOURCES) { +                        if (block_state == BLOCK_ENTRY || block_state == BLOCK_LISTING) {                              if (if_count > 0) {                                  state = TEMPLATE_BLOCK_END;                                  type = BLOGC_TEMPLATE_ENDIF_STMT; @@ -169,14 +169,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' statements only allowed inside 'single_source' " -                            "and 'multiple_sources' blocks."); +                            "'endif' statements only allowed inside 'entry' " +                            "and 'listing' blocks.");                          break;                      }                  }                  *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,                      src_len, current, -                    "Invalid statement type: Allowed types are: block, endblock, if, endif."); +                    "Invalid statement type: Allowed types are: 'block', " +                    "'endblock', 'if' and 'endif'.");                  break;              case TEMPLATE_BLOCK_BLOCK_TYPE_START: @@ -196,20 +197,20 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)                  if ((c >= 'a' && c <= 'z') || c == '_')                      break;                  if (c == ' ') { -                    if (0 == strncmp("single_source", src + start, current - start)) { -                        block_state = BLOCK_SINGLE_SOURCE; +                    if (0 == strncmp("entry", src + start, current - start)) { +                        block_state = BLOCK_ENTRY;                          end = current;                          state = TEMPLATE_BLOCK_END;                          break;                      } -                    else if (0 == strncmp("multiple_sources", src + start, current - start)) { -                        block_state = BLOCK_MULTIPLE_SOURCES; +                    else if (0 == strncmp("listing", src + start, current - start)) { +                        block_state = BLOCK_LISTING;                          end = current;                          state = TEMPLATE_BLOCK_END;                          break;                      } -                    else if (0 == strncmp("multiple_sources_once", src + start, current - start)) { -                        block_state = BLOCK_MULTIPLE_SOURCES_ONCE; +                    else if (0 == strncmp("listing_once", src + start, current - start)) { +                        block_state = BLOCK_LISTING_ONCE;                          end = current;                          state = TEMPLATE_BLOCK_END;                          break; @@ -217,7 +218,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 block type. Allowed types are: single_source, multiple_sources, multiple_sources_once."); +                    "Invalid block type. Allowed types are: 'entry', 'listing' " +                    "and 'listing_once'.");                  break;              case TEMPLATE_BLOCK_IF_VARIABLE_START: @@ -243,7 +245,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 variable name. Must be uppercase letter, number or '_'."); +                    "Invalid variable name. Must be uppercase letter, number " +                    "or '_'.");                  break;              case TEMPLATE_BLOCK_END: @@ -262,7 +265,7 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)                  if (c == ' ')                      break;                  if (c >= 'A' && c <= 'Z') { -                    if (block_state == BLOCK_SINGLE_SOURCE || block_state == BLOCK_MULTIPLE_SOURCES) { +                    if (block_state == BLOCK_ENTRY || block_state == BLOCK_LISTING) {                          state = TEMPLATE_VARIABLE;                          type = BLOGC_TEMPLATE_VARIABLE_STMT;                          start = current; @@ -270,8 +273,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, -                        "variable statements only allowed inside 'single_source' " -                        "and 'multiple_sources' blocks."); +                        "variable statements only allowed inside 'entry' and " +                        "'listing' blocks.");                      break;                  }                  *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src, @@ -294,7 +297,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 variable name. Must be uppercase letter, number or '_'."); +                    "Invalid variable name. Must be uppercase letter, number " +                    "or '_'.");                  break;              case TEMPLATE_VARIABLE_END: @@ -339,10 +343,10 @@ 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 'if' statements were not closed!", if_count); +                "%d open 'if' statements were not closed!", if_count);          else if (block_state != BLOCK_CLOSED)              *err = blogc_error_new(BLOGC_ERROR_TEMPLATE_PARSER, -                "A block was not closed!"); +                "An open block was not closed!");      }      if (*err != NULL) { | 
