aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRafael G. Martins <rafael@rafaelmartins.eng.br>2015-04-27 00:10:26 -0300
committerRafael G. Martins <rafael@rafaelmartins.eng.br>2015-04-27 00:10:26 -0300
commit5205db347cb9f56187c2ad5e767281a7a4016533 (patch)
tree946917c0bbcfd17a6cd02b3bc03fd7f37fdb6cc9 /src
parent2dfa0fbac45122567988cb520e508f24897114fe (diff)
downloadblogc-5205db347cb9f56187c2ad5e767281a7a4016533.tar.gz
blogc-5205db347cb9f56187c2ad5e767281a7a4016533.tar.bz2
blogc-5205db347cb9f56187c2ad5e767281a7a4016533.zip
added global variable support
Diffstat (limited to 'src')
-rw-r--r--src/main.c54
-rw-r--r--src/renderer.c80
-rw-r--r--src/renderer.h3
-rw-r--r--src/template-parser.c46
4 files changed, 108 insertions, 75 deletions
diff --git a/src/main.c b/src/main.c
index e43b71b..0680728 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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,