aboutsummaryrefslogtreecommitdiffstats
path: root/src/blogc-make/settings.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/blogc-make/settings.c')
-rw-r--r--src/blogc-make/settings.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/blogc-make/settings.c b/src/blogc-make/settings.c
new file mode 100644
index 0000000..e2789dc
--- /dev/null
+++ b/src/blogc-make/settings.c
@@ -0,0 +1,175 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <libgen.h>
+#include <stdlib.h>
+#include "../common/config-parser.h"
+#include "../common/error.h"
+#include "../common/file.h"
+#include "../common/utils.h"
+#include "settings.h"
+
+
+static const struct default_settings_map {
+ const char *key;
+ const char *default_value;
+} default_settings[] = {
+
+ // source
+ {"content_dir", "content"},
+ {"template_dir", "templates"},
+ {"main_template", "main.tmpl"},
+ {"source_ext", ".txt"},
+
+ // output
+ {"output_dir", "_build"},
+
+ // pagination
+ {"pagination_prefix", "page"},
+ {"posts_per_page", "10"},
+ {"atom_posts_per_page", "10"},
+
+ // html
+ {"html_ext", "/index.html"},
+ {"index_prefix", NULL},
+ {"post_prefix", "post"},
+ {"tag_prefix", "tag"},
+
+ // atom
+ {"atom_prefix", "atom"},
+ {"atom_ext", ".xml"},
+
+ // generic
+ {"date_format", "%b %d, %Y, %I:%M %p GMT"},
+ {"locale", NULL},
+
+ {NULL, NULL},
+};
+
+
+static const char* required_environment[] = {
+ "AUTHOR_NAME",
+ "AUTHOR_EMAIL",
+ "SITE_TITLE",
+ "SITE_TAGLINE",
+ "BASE_DOMAIN",
+ NULL,
+};
+
+
+static const char* list_sections[] = {
+ "posts",
+ "pages",
+ "copy_files",
+ "tags",
+ NULL,
+};
+
+
+bm_settings_t*
+bm_settings_parse(const char *content, size_t content_len, bc_error_t **err)
+{
+ if (err == NULL || *err != NULL)
+ return NULL;
+
+ if (content == NULL)
+ return NULL;
+
+ bc_config_t *config = bc_config_parse(content, content_len, list_sections,
+ err);
+ if (config == NULL || (err != NULL && *err != NULL))
+ return NULL;
+
+ bm_settings_t *rv = bc_malloc(sizeof(bm_settings_t));
+ rv->root_dir = NULL;
+ rv->env = bc_trie_new(free);
+ rv->settings = bc_trie_new(free);
+ rv->posts = NULL;
+ rv->pages = NULL;
+ rv->copy_files = NULL;
+ rv->tags = NULL;
+
+ char **env = bc_config_list_keys(config, "environment");
+ if (env != NULL) {
+ for (size_t i = 0; env[i] != NULL; i++) {
+ // FIXME: validate keys
+ bc_trie_insert(rv->env, env[i],
+ bc_strdup(bc_config_get(config, "environment", env[i])));
+ }
+ }
+ bc_strv_free(env);
+
+ for (size_t i = 0; required_environment[i] != NULL; i++) {
+ const char *value = bc_trie_lookup(rv->env, required_environment[i]);
+ if (value == NULL || value[0] == '\0') {
+ *err = bc_error_new_printf(BLOGC_MAKE_ERROR_SETTINGS,
+ "[environment] key required but not found or empty: %s",
+ required_environment[i]);
+ bm_settings_free(rv);
+ rv = NULL;
+ goto cleanup;
+ }
+ }
+
+ for (size_t i = 0; default_settings[i].key != NULL; i++) {
+ const char *value = bc_config_get_with_default(
+ config, "settings", default_settings[i].key,
+ default_settings[i].default_value);
+ if (value != NULL) {
+ bc_trie_insert(rv->settings, default_settings[i].key,
+ bc_strdup(value));
+ }
+ }
+
+ rv->posts = bc_config_get_list(config, "posts");
+ rv->pages = bc_config_get_list(config, "pages");
+ rv->copy_files = bc_config_get_list(config, "copy_files");
+ rv->tags = bc_config_get_list(config, "tags");
+
+cleanup:
+
+ bc_config_free(config);
+
+ return rv;
+}
+
+
+bm_settings_t*
+bm_settings_parse_file(const char *filename, bc_error_t **err)
+{
+ if (err == NULL || *err != NULL)
+ return NULL;
+
+ size_t content_len;
+ char *content = bc_file_get_contents(filename, true, &content_len, err);
+ if (*err != NULL)
+ return NULL;
+
+ bm_settings_t *rv = bm_settings_parse(content, content_len, err);
+ char *real_filename = realpath(filename, NULL);
+ rv->root_dir = bc_strdup(dirname(real_filename));
+ free(real_filename);
+ free(content);
+ return rv;
+}
+
+
+void
+bm_settings_free(bm_settings_t *settings)
+{
+ if (settings == NULL)
+ return;
+ free(settings->root_dir);
+ bc_trie_free(settings->env);
+ bc_trie_free(settings->settings);
+ bc_strv_free(settings->posts);
+ bc_strv_free(settings->pages);
+ bc_strv_free(settings->copy_files);
+ bc_strv_free(settings->tags);
+ free(settings);
+}