aboutsummaryrefslogtreecommitdiffstats
path: root/src/blogc-make
diff options
context:
space:
mode:
Diffstat (limited to 'src/blogc-make')
-rw-r--r--src/blogc-make/ctx.c108
-rw-r--r--src/blogc-make/ctx.h3
-rw-r--r--src/blogc-make/rules.c48
-rw-r--r--src/blogc-make/settings.c1
4 files changed, 136 insertions, 24 deletions
diff --git a/src/blogc-make/ctx.c b/src/blogc-make/ctx.c
index 423b334..d7a503d 100644
--- a/src/blogc-make/ctx.c
+++ b/src/blogc-make/ctx.c
@@ -13,6 +13,7 @@
#include <libgen.h>
#include <limits.h>
#include <time.h>
+#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
@@ -267,7 +268,11 @@ bm_ctx_new(bm_ctx_t *base, const char *settings_file, const char *argv0,
}
rv->posts_fctx = NULL;
- if (settings->posts != NULL) {
+ rv->posts_deleted = false;
+ if (bc_str_to_bool(bc_trie_lookup(settings->settings, "posts_autoload"))) {
+ bm_ctx_autoload_posts(rv);
+ }
+ else if (settings->posts != NULL) {
for (size_t i = 0; settings->posts[i] != NULL; i++) {
char *f = bm_generate_filename(content_dir, post_prefix,
settings->posts[i], source_ext);
@@ -306,7 +311,7 @@ bm_ctx_reload(bm_ctx_t **ctx)
if (*ctx == NULL || (*ctx)->settings_fctx == NULL)
return false;
- if (bm_filectx_changed((*ctx)->settings_fctx, NULL, NULL)) {
+ if ((*ctx)->posts_deleted || bm_filectx_changed((*ctx)->settings_fctx, NULL, NULL)) {
// reload everything! we could just reload settings_fctx, as this
// would force rebuilding everything, but we need to know new/deleted
// files
@@ -328,8 +333,13 @@ bm_ctx_reload(bm_ctx_t **ctx)
bm_filectx_reload((*ctx)->atom_template_fctx);
bm_filectx_reload((*ctx)->listing_entry_fctx);
- for (bc_slist_t *tmp = (*ctx)->posts_fctx; tmp != NULL; tmp = tmp->next)
- bm_filectx_reload((bm_filectx_t*) tmp->data);
+ if (bc_str_to_bool(bm_ctx_settings_lookup(*ctx, "posts_autoload"))) {
+ bm_ctx_autoload_posts(*ctx);
+ }
+ else {
+ for (bc_slist_t *tmp = (*ctx)->posts_fctx; tmp != NULL; tmp = tmp->next)
+ bm_filectx_reload((bm_filectx_t*) tmp->data);
+ }
for (bc_slist_t *tmp = (*ctx)->pages_fctx; tmp != NULL; tmp = tmp->next)
bm_filectx_reload((bm_filectx_t*) tmp->data);
@@ -342,6 +352,96 @@ bm_ctx_reload(bm_ctx_t **ctx)
void
+bm_ctx_autoload_posts(bm_ctx_t *ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ const char *content_dir = bm_ctx_settings_lookup(ctx, "content_dir");
+ const char *post_prefix = bm_ctx_settings_lookup(ctx, "post_prefix");
+ const char *source_ext = bm_ctx_settings_lookup(ctx, "source_ext");
+
+ char *posts_dir = bm_generate_filename(content_dir, post_prefix, NULL, NULL);
+ char *abs_posts_dir = bc_strdup_printf("%s/%s", ctx->root_dir, posts_dir);
+ DIR *dir = opendir(abs_posts_dir);
+ if (dir == NULL) {
+ fprintf(stderr,
+ "blogc-make: warning: failed to open directory for posts autoload "
+ "(%s): %s\n", abs_posts_dir, strerror(errno));
+ free(posts_dir);
+ free(abs_posts_dir);
+ return;
+ }
+ free(abs_posts_dir);
+
+ // trick 0: avoid additional loops if we are not reloading
+ bool reloading = ctx->posts_fctx != NULL;
+
+ // trick 1: set all the post file contexts as unreadable, so we can detect
+ // which ones were deleted.
+ for (bc_slist_t *tmp = ctx->posts_fctx; tmp != NULL; tmp = tmp->next) {
+ bm_filectx_t *fc = tmp->data;
+ if (fc->readable) {
+ fc->readable = false;
+ }
+ }
+
+ struct dirent *e;
+ while (NULL != (e = readdir(dir))) {
+ if ((0 == strcmp(e->d_name, ".")) || (0 == strcmp(e->d_name, "..")))
+ continue;
+ if (!bc_str_ends_with(e->d_name, source_ext))
+ continue;
+ char *tmp = bc_strdup_printf("%s/%s", posts_dir, e->d_name);
+
+ // trick 2: if the file context exists in the index, just set it as
+ // readable
+ bm_filectx_t *fc = NULL;
+ if (reloading) {
+ for (bc_slist_t *t = ctx->posts_fctx; t != NULL; t = t->next) {
+ bm_filectx_t *fct = t->data;
+ if (0 == strcmp(fct->short_path, tmp)) {
+ fc = fct;
+ break;
+ }
+ }
+ }
+ if (fc != NULL) {
+ fc->readable = true;
+ bm_filectx_reload(fc);
+ }
+ else {
+ e->d_name[strlen(e->d_name) - strlen(source_ext)] = 0;
+ fc = bm_filectx_new(ctx, tmp, e->d_name, NULL);
+ ctx->posts_fctx = bc_slist_append(ctx->posts_fctx, fc);
+ }
+ free(tmp);
+ }
+
+ // trick 3: delete the unreadable file contexts
+ ctx->posts_deleted = false;
+ if (reloading) {
+ for (bc_slist_t *tmp = ctx->posts_fctx; tmp != NULL;) {
+ bm_filectx_t *fc = tmp->data;
+ if (!fc->readable) {
+ bc_slist_t *next = tmp->next;
+ ctx->posts_fctx = bc_slist_remove(ctx->posts_fctx, tmp,
+ (bc_free_func_t) bm_filectx_free);
+ tmp = next;
+ ctx->posts_deleted = true;
+ }
+ else {
+ tmp = tmp->next;
+ }
+ }
+ }
+
+ closedir(dir);
+ free(posts_dir);
+}
+
+
+void
bm_ctx_free_internal(bm_ctx_t *ctx)
{
if (ctx == NULL)
diff --git a/src/blogc-make/ctx.h b/src/blogc-make/ctx.h
index a66d51c..43284a5 100644
--- a/src/blogc-make/ctx.h
+++ b/src/blogc-make/ctx.h
@@ -63,8 +63,10 @@ typedef struct {
bm_filectx_t *listing_entry_fctx;
bc_slist_t *posts_fctx;
+ bool posts_deleted;
bc_slist_t *pages_fctx;
bc_slist_t *copy_fctx;
+
} bm_ctx_t;
bm_filectx_t* bm_filectx_new(bm_ctx_t *ctx, const char *filename, const char *slug,
@@ -76,6 +78,7 @@ void bm_filectx_free(bm_filectx_t *fctx);
bm_ctx_t* bm_ctx_new(bm_ctx_t *base, const char *settings_file,
const char *argv0, bc_error_t **err);
bool bm_ctx_reload(bm_ctx_t **ctx);
+void bm_ctx_autoload_posts(bm_ctx_t *ctx);
void bm_ctx_free_internal(bm_ctx_t *ctx);
void bm_ctx_free(bm_ctx_t *ctx);
const char* bm_ctx_settings_lookup(bm_ctx_t *ctx, const char *key);
diff --git a/src/blogc-make/rules.c b/src/blogc-make/rules.c
index 96cf51d..f42b99a 100644
--- a/src/blogc-make/rules.c
+++ b/src/blogc-make/rules.c
@@ -32,7 +32,9 @@ posts_ordering(bm_ctx_t *ctx, bc_trie_t *variables, const char *variable)
const char *value = bm_ctx_settings_lookup_str(ctx, variable);
bool asc = 0 == strcasecmp(value, "asc");
- bool sort = bc_str_to_bool(bm_ctx_settings_lookup(ctx, "posts_sort"));
+ bool posts_autoload = bc_str_to_bool(bm_ctx_settings_lookup(ctx, "posts_autoload"));
+ bool posts_sort = bc_str_to_bool(bm_ctx_settings_lookup(ctx, "posts_sort"));
+ bool sort = posts_sort || posts_autoload;
if (sort) {
bc_trie_insert(variables, "FILTER_SORT", bc_strdup("1"));
@@ -75,7 +77,7 @@ posts_pagination_enabled(bm_ctx_t *ctx, const char *variable)
static bc_slist_t*
index_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return NULL;
if (!posts_pagination_enabled(ctx, "posts_per_page"))
@@ -97,7 +99,7 @@ index_outputlist(bm_ctx_t *ctx)
static int
index_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return 0;
int rv = 0;
@@ -114,7 +116,8 @@ index_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
bm_filectx_t *fctx = l->data;
if (fctx == NULL)
continue;
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
+ if (ctx->posts_deleted ||
+ bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
ctx->listing_entry_fctx, ctx->main_template_fctx, fctx, false))
{
rv = bm_exec_blogc(ctx, variables, NULL, true, ctx->listing_entry_fctx,
@@ -135,7 +138,7 @@ index_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
static bc_slist_t*
atom_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return NULL;
if (!posts_pagination_enabled(ctx, "atom_posts_per_page"))
@@ -157,7 +160,7 @@ atom_outputlist(bm_ctx_t *ctx)
static int
atom_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return 0;
int rv = 0;
@@ -173,7 +176,8 @@ atom_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
bm_filectx_t *fctx = l->data;
if (fctx == NULL)
continue;
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx, NULL, NULL,
+ if (ctx->posts_deleted ||
+ bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx, NULL, NULL,
fctx, false))
{
rv = bm_exec_blogc(ctx, variables, NULL, true, NULL, ctx->atom_template_fctx,
@@ -194,7 +198,7 @@ atom_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
static bc_slist_t*
atom_tags_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL || ctx->settings->tags == NULL)
return NULL;
if (!posts_pagination_enabled(ctx, "atom_posts_per_page"))
@@ -218,7 +222,7 @@ atom_tags_outputlist(bm_ctx_t *ctx)
static int
atom_tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL || ctx->settings->tags == NULL)
return 0;
int rv = 0;
@@ -239,7 +243,8 @@ atom_tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
bc_trie_insert(variables, "FILTER_TAG",
bc_strdup(ctx->settings->tags[i]));
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx, NULL, NULL,
+ if (ctx->posts_deleted ||
+ bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx, NULL, NULL,
fctx, false))
{
rv = bm_exec_blogc(ctx, variables, NULL, true, NULL, ctx->atom_template_fctx,
@@ -260,7 +265,7 @@ atom_tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
static bc_slist_t*
pagination_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return NULL;
// not using posts_pagination_enabled() here because we need to calculate
@@ -293,7 +298,7 @@ pagination_outputlist(bm_ctx_t *ctx)
static int
pagination_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return 0;
int rv = 0;
@@ -315,7 +320,8 @@ pagination_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
if (fctx == NULL)
continue;
bc_trie_insert(variables, "FILTER_PAGE", bc_strdup_printf("%zu", page));
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
+ if (ctx->posts_deleted ||
+ bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
ctx->listing_entry_fctx, ctx->main_template_fctx, fctx, false))
{
rv = bm_exec_blogc(ctx, variables, NULL, true, ctx->listing_entry_fctx,
@@ -336,7 +342,7 @@ pagination_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
static bc_slist_t*
posts_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return NULL;
bc_slist_t *rv = NULL;
@@ -344,9 +350,10 @@ posts_outputlist(bm_ctx_t *ctx)
const char *post_prefix = bm_ctx_settings_lookup(ctx, "post_prefix");
const char *html_ext = bm_ctx_settings_lookup(ctx, "html_ext");
- for (size_t i = 0; ctx->settings->posts[i] != NULL; i++) {
+ for (bc_slist_t *l = ctx->posts_fctx; l != NULL; l = l->next) {
+ bm_filectx_t *fc = l->data;
char *f = bm_generate_filename(ctx->short_output_dir, post_prefix,
- ctx->settings->posts[i], html_ext);
+ fc->slug, html_ext);
rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
free(f);
}
@@ -357,7 +364,7 @@ posts_outputlist(bm_ctx_t *ctx)
static int
posts_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return 0;
int rv = 0;
@@ -403,7 +410,7 @@ posts_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
static bc_slist_t*
tags_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL || ctx->settings->tags == NULL)
return NULL;
if (!posts_pagination_enabled(ctx, "posts_per_page"))
@@ -427,7 +434,7 @@ tags_outputlist(bm_ctx_t *ctx)
static int
tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL || ctx->settings->tags == NULL)
return 0;
int rv = 0;
@@ -449,7 +456,8 @@ tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
bc_trie_insert(variables, "FILTER_TAG",
bc_strdup(ctx->settings->tags[i]));
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
+ if (ctx->posts_deleted ||
+ bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
ctx->listing_entry_fctx, ctx->main_template_fctx, fctx, false))
{
rv = bm_exec_blogc(ctx, variables, NULL, true, ctx->listing_entry_fctx,
diff --git a/src/blogc-make/settings.c b/src/blogc-make/settings.c
index be976e3..2f56d9c 100644
--- a/src/blogc-make/settings.c
+++ b/src/blogc-make/settings.c
@@ -28,6 +28,7 @@ static const struct default_settings_map {
{"main_template", "main.tmpl"},
{"source_ext", ".txt"},
{"listing_entry", NULL},
+ {"posts_autoload", NULL},
{"posts_sort", NULL},
// pagination