diff options
| author | Rafael G. Martins <rafael@rafaelmartins.eng.br> | 2015-04-27 00:10:26 -0300 | 
|---|---|---|
| committer | Rafael G. Martins <rafael@rafaelmartins.eng.br> | 2015-04-27 00:10:26 -0300 | 
| commit | 5205db347cb9f56187c2ad5e767281a7a4016533 (patch) | |
| tree | 946917c0bbcfd17a6cd02b3bc03fd7f37fdb6cc9 /src | |
| parent | 2dfa0fbac45122567988cb520e508f24897114fe (diff) | |
| download | blogc-5205db347cb9f56187c2ad5e767281a7a4016533.tar.gz blogc-5205db347cb9f56187c2ad5e767281a7a4016533.tar.bz2 blogc-5205db347cb9f56187c2ad5e767281a7a4016533.zip | |
added global variable support
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 54 | ||||
| -rw-r--r-- | src/renderer.c | 80 | ||||
| -rw-r--r-- | src/renderer.h | 3 | ||||
| -rw-r--r-- | src/template-parser.c | 46 | 
4 files changed, 108 insertions, 75 deletions
| @@ -36,24 +36,25 @@ blogc_print_help(void)  {      printf(          "usage:\n" -        "    blogc [-h] [-v] [-l] -t TEMPLATE [-o OUTPUT] SOURCE [SOURCE ...] - A blog compiler.\n" +        "    blogc [-h] [-v] [-l] [-D KEY=VALUE ...] -t TEMPLATE [-o OUTPUT] SOURCE [SOURCE ...] - A blog compiler.\n"          "\n"          "positional arguments:\n" -        "    SOURCE       source file(s)\n" +        "    SOURCE        source file(s)\n"          "\n"          "optional arguments:\n" -        "    -h           show this help message and exit\n" -        "    -v           show version and exit\n" -        "    -l           build listing page, from multiple source files\n" -        "    -t TEMPLATE  template file\n" -        "    -o OUTPUT    output file\n"); +        "    -h            show this help message and exit\n" +        "    -v            show version and exit\n" +        "    -l            build listing page, from multiple source files\n" +        "    -D KEY=VALUE  set global configuration parameter\n" +        "    -t TEMPLATE   template file\n" +        "    -o OUTPUT     output file\n");  }  static void  blogc_print_usage(void)  { -    printf("usage: blogc [-h] [-v] [-l] -t TEMPLATE [-o OUTPUT] SOURCE [SOURCE ...]\n"); +    printf("usage: blogc [-h] [-v] [-l] [-D KEY=VALUE ...] -t TEMPLATE [-o OUTPUT] SOURCE [SOURCE ...]\n");  } @@ -100,9 +101,14 @@ main(int argc, char **argv)      bool listing = false;      char *template = NULL;      char *output = NULL; +    char *tmp = NULL; +    char **pieces = NULL; +      b_slist_t *sources = NULL; +    b_trie_t *config = b_trie_new(free);      for (unsigned int i = 1; i < argc; i++) { +        tmp = NULL;          if (argv[i][0] == '-') {              switch (argv[i][1]) {                  case 'h': @@ -126,6 +132,35 @@ main(int argc, char **argv)                      else if (i + 1 < argc)                          output = b_strdup(argv[++i]);                      break; +                case 'D': +                    if (argv[i][2] != '\0') +                        tmp = argv[i] + 2; +                    else if (i + 1 < argc) +                        tmp = argv[++i]; +                    if (tmp != NULL) { +                        pieces = b_str_split(tmp, '=', 2); +                        if (b_strv_length(pieces) != 2) { +                            fprintf(stderr, "blogc: error: invalid value for " +                                "-D (must have an '='): %s\n", tmp); +                            b_strv_free(pieces); +                            rv = 2; +                            goto cleanup; +                        } +                        for (unsigned int j = 0; pieces[0][j] != '\0'; j++) { +                            if (!(pieces[0][j] >= 'A' && pieces[0][j] <= 'Z')) { +                                fprintf(stderr, "blogc: error: invalid value " +                                    "for -D (configuration key must be uppercase): " +                                    "%s\n", pieces[0]); +                                b_strv_free(pieces); +                                rv = 2; +                                goto cleanup; +                            } +                        } +                        b_trie_insert(config, pieces[0], b_strdup(pieces[1])); +                        b_strv_free(pieces); +                        pieces = NULL; +                    } +                    break;                  default:                      blogc_print_usage();                      fprintf(stderr, "blogc: error: invalid argument: -%c\n", @@ -177,7 +212,7 @@ main(int argc, char **argv)          goto cleanup3;      } -    char *out = blogc_render(l, s, listing); +    char *out = blogc_render(l, s, config, listing);      bool write_to_stdout = (output == NULL || (0 == strcmp(output, "-"))); @@ -206,6 +241,7 @@ cleanup2:      blogc_template_free_stmts(l);      blogc_error_free(err);  cleanup: +    b_trie_free(config);      free(template);      free(output);      b_slist_free_full(sources, free); diff --git a/src/renderer.c b/src/renderer.c index 92fa7d4..905c42f 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -18,7 +18,7 @@  char* -blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing) +blogc_render(b_slist_t *tmpl, b_slist_t *sources, b_trie_t *config, bool listing)  {      if (tmpl == NULL || sources == NULL)          return NULL; @@ -35,6 +35,7 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing)      unsigned int if_skip = 0;      bool if_not = false; +    bool defined = false;      b_slist_t *tmp = tmpl;      while (tmp != NULL) { @@ -86,11 +87,25 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing)                  break;              case BLOGC_TEMPLATE_VARIABLE_STMT: -                if (stmt->value != NULL && tmp_source != NULL) { -                    config_value = b_trie_lookup(tmp_source, stmt->value); -                    if (config_value != NULL) -                        b_string_append(str, config_value); -                    break; +                if (stmt->value != NULL) { + +                    // try local config first +                    if (tmp_source != NULL) { +                        config_value = b_trie_lookup(tmp_source, stmt->value); +                        if (config_value != NULL) { +                            b_string_append(str, config_value); +                            break; +                        } +                    } + +                    // if not found, try global config +                    if (config != NULL) { +                        config_value = b_trie_lookup(config, stmt->value); +                        if (config_value != NULL) { +                            b_string_append(str, config_value); +                            break; +                        } +                    }                  }                  break; @@ -110,36 +125,39 @@ blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing)                  if_not = true;              case BLOGC_TEMPLATE_IF_STMT: -                if (stmt->value != NULL && tmp_source != 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 -                        // 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_IF_NOT_STMT)) -                            { -                                if_count++; +                defined = false; +                if (stmt->value != NULL) { +                    if (tmp_source != NULL && b_trie_lookup(tmp_source, stmt->value) != NULL) +                        defined = true; +                    if (config != NULL && b_trie_lookup(config, stmt->value) != NULL) +                        defined = true; +                } +                if ((!if_not && !defined) || (if_not && defined)) { +                    if_skip = if_count; + +                    // 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_IF_NOT_STMT)) +                        { +                            if_count++; +                            continue; +                        } +                        if (stmt->type == BLOGC_TEMPLATE_ENDIF_STMT) { +                            if (if_count > if_skip) { +                                if_count--;                                  continue;                              } -                            if (stmt->type == BLOGC_TEMPLATE_ENDIF_STMT) { -                                if (if_count > if_skip) { -                                    if_count--; -                                    continue; -                                } -                                if (if_count == if_skip) -                                    break; -                            } +                            if (if_count == if_skip) +                                break;                          }                      } -                    if_not = false;                  } +                if_not = false;                  break;              case BLOGC_TEMPLATE_ENDIF_STMT: diff --git a/src/renderer.h b/src/renderer.h index a6b7a2c..c9a0ed1 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -12,6 +12,7 @@  #include <stdbool.h>  #include "utils/utils.h" -char* blogc_render(b_slist_t *tmpl, b_slist_t *sources, bool listing); +char* blogc_render(b_slist_t *tmpl, b_slist_t *sources, b_trie_t *config, +    bool listing);  #endif /* _RENDERER_H */ diff --git a/src/template-parser.c b/src/template-parser.c index 69402cf..a91182f 100644 --- a/src/template-parser.c +++ b/src/template-parser.c @@ -143,36 +143,22 @@ 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_ENTRY || block_state == BLOCK_LISTING) { -                            state = TEMPLATE_BLOCK_IF_START; -                            type = BLOGC_TEMPLATE_IF_STMT; -                            start = current; -                            if_count++; -                            break; -                        } -                        *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, -                            src, src_len, current, -                            "'if' statements only allowed inside 'entry' and " -                            "'listing' blocks."); +                        state = TEMPLATE_BLOCK_IF_START; +                        type = BLOGC_TEMPLATE_IF_STMT; +                        start = current; +                        if_count++;                          break;                      }                      else if (0 == strncmp("endif", src + start, current - start)) { -                        if (block_state == BLOCK_ENTRY || block_state == BLOCK_LISTING) { -                            if (if_count > 0) { -                                state = TEMPLATE_BLOCK_END; -                                type = BLOGC_TEMPLATE_ENDIF_STMT; -                                if_count--; -                                break; -                            } -                            *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, -                                src, src_len, current, -                                "'endif' statement without an open 'if' statement."); +                        if (if_count > 0) { +                            state = TEMPLATE_BLOCK_END; +                            type = BLOGC_TEMPLATE_ENDIF_STMT; +                            if_count--;                              break;                          }                          *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER,                              src, src_len, current, -                            "'endif' statements only allowed inside 'entry' " -                            "and 'listing' blocks."); +                            "'endif' statement without an open 'if' statement.");                          break;                      }                  } @@ -250,7 +236,6 @@ blogc_template_parse(const char *src, size_t src_len, blogc_error_t **err)                      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; @@ -293,16 +278,9 @@ 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_ENTRY || block_state == BLOCK_LISTING) { -                        state = TEMPLATE_VARIABLE; -                        type = BLOGC_TEMPLATE_VARIABLE_STMT; -                        start = current; -                        break; -                    } -                    *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, -                        src, src_len, current, -                        "Variable statements only allowed inside 'entry' and " -                        "'listing' blocks."); +                    state = TEMPLATE_VARIABLE; +                    type = BLOGC_TEMPLATE_VARIABLE_STMT; +                    start = current;                      break;                  }                  *err = blogc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src, | 
