From 75906fbb296d2ed7cd9ca05e1b7bf0c92f84a30b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Yaroslav=20de=20la=20Pe=C3=B1a=20Smirnov?=
 <yps@yaroslavps.com>
Date: Thu, 24 Mar 2022 01:09:48 +0300
Subject: Switch from unja to roscha

Still a WIP, some bugs need to be fixed.

Also change the license to GPL from LGPL. It was always meant to be GPL,
not sure what brain fart caused this.
---
 src/components.c |  23 +++++----
 src/fs.c         |  20 ++++----
 src/render.c     | 146 ++++++++++++++++++++++++-------------------------------
 src/revela.c     |   1 -
 src/site.c       |  22 ++++++---
 5 files changed, 100 insertions(+), 112 deletions(-)

(limited to 'src')

diff --git a/src/components.c b/src/components.c
index bb610fe..fc3bab5 100644
--- a/src/components.c
+++ b/src/components.c
@@ -10,6 +10,7 @@
 #include "fs.h"
 #include "log.h"
 #include "site.h"
+#include "roscha.h"
 
 #define MAXTIME \
 	((unsigned long long)1 << ((sizeof(time_t) * CHAR_BIT) - 1)) - 1
@@ -166,8 +167,8 @@ image_new(char *src, const struct stat *pstat, struct album *album)
 	image->exif_data = exif_data_new_from_file(image->source);
 	image->modtime = pstat->st_mtim;
 	image_set_date(image, pstat);
-	image->map = hashmap_new_with_cap(8);
-	image->thumb = hashmap_new_with_cap(4);
+	image->map = roscha_object_new(hmap_new_with_cap(8));
+	image->thumb = roscha_object_new(hmap_new_with_cap(4));
 	image->modified = false;
 
 	return image;
@@ -193,8 +194,8 @@ image_destroy(void *data)
 		exif_data_unref(image->exif_data);
 	}
 	if (image->map) {
-		hashmap_free(image->map);
-		hashmap_free(image->thumb);
+		roscha_object_unref(image->map);
+		roscha_object_unref(image->thumb);
 	}
 	free(image);
 }
@@ -214,10 +215,9 @@ album_new(struct album_config *conf, struct site *site, const char *src,
 	album->slug = slugify(rsrc, site->config->base_url, &album->url);
 	album->images = bstree_new(image_cmp, image_destroy);
 	album->tstamp = MAXTIME;
-	album->preserved = hashmap_new();
-	album->map = hashmap_new_with_cap(16);
-	album->thumbs = vector_new(128);
-	album->previews = vector_new(site->config->max_previews);
+	album->preserved = hmap_new();
+	album->map = roscha_object_new(hmap_new());
+	album->thumbs = roscha_object_new(vector_new());
 
 	return album;
 }
@@ -260,9 +260,8 @@ album_destroy(void *data)
 	free(album->source);
 	free(album->url);
 	bstree_destroy(album->images);
-	hashmap_free(album->preserved);
-	hashmap_free(album->map);
-	vector_free(album->thumbs);
-	vector_free(album->previews);
+	hmap_free(album->preserved);
+	roscha_object_unref(album->map);
+	roscha_object_unref(album->thumbs);
 	free(album);
 }
diff --git a/src/fs.c b/src/fs.c
index 49d6e0d..b6ec372 100644
--- a/src/fs.c
+++ b/src/fs.c
@@ -2,7 +2,9 @@
 
 #include "log.h"
 #include "config.h"
+
 #include "vector.h"
+#include "slice.h"
 
 #include <fcntl.h>
 #include <stdio.h>
@@ -37,7 +39,7 @@ static const char *img_extensions[] = {
 };
 
 static void
-hm_destroy_callback(const void *k, void *v)
+hm_destroy_cb(const struct slice *k, void *v)
 {
 	free(v);
 }
@@ -199,7 +201,7 @@ error:
 }
 
 ssize_t
-rmextra(const char *path, struct hashmap *preserved, preremove_fn cb,
+rmextra(const char *path, struct hmap *preserved, preremove_fn cb,
 		void *data, bool dry)
 {
 	ssize_t removed = 0;
@@ -212,7 +214,7 @@ rmextra(const char *path, struct hashmap *preserved, preremove_fn cb,
 			continue;
 		}
 
-		if (hashmap_get(preserved, ent->d_name) != NULL) continue;
+		if (hmap_get(preserved, ent->d_name) != NULL) continue;
 
 		char target[PATH_MAX];
 		sprintf(target, "%s/%s", path, ent->d_name);
@@ -232,7 +234,7 @@ rmextra(const char *path, struct hashmap *preserved, preremove_fn cb,
 
 bool
 filesync(const char *restrict srcpath, const char *restrict dstpath,
-		struct hashmap *preserved, bool dry)
+		struct hmap *preserved, bool dry)
 {
 	int fdsrc;
 	struct stat stsrc;
@@ -271,9 +273,9 @@ filesync(const char *restrict srcpath, const char *restrict dstpath,
 
 		if (cleanup) {
 			if (preserved == NULL) {
-				preserved = hashmap_new();
+				preserved = hmap_new();
 			} else {
-				own = vector_new(32);
+				own = vector_new_with_cap(32);
 			}
 		}
 
@@ -293,7 +295,7 @@ filesync(const char *restrict srcpath, const char *restrict dstpath,
 			sprintf(entdst, "%s/%s", dstpath, ent->d_name);
 			if (cleanup) {
 				char *name = strdup(ent->d_name);
-				hashmap_insert(preserved, name, name);
+				hmap_set(preserved, name, name);
 				if (own) {
 					vector_push(own, name);
 				}
@@ -307,12 +309,12 @@ filesync(const char *restrict srcpath, const char *restrict dstpath,
 		if (cleanup) {
 			rmextra(dstpath, preserved, NULL, NULL, dry);
 			if (own) {
-				for (size_t i = 0; i < own->size; i++) {
+				for (size_t i = 0; i < own->len; i++) {
 					free(own->values[i]);
 				}
 				vector_free(own);
 			} else {
-				hashmap_destroy(preserved, hm_destroy_callback);
+				hmap_destroy(preserved, hm_destroy_cb);
 			}
 		}
 
diff --git a/src/render.c b/src/render.c
index 17436f8..79e5245 100644
--- a/src/render.c
+++ b/src/render.c
@@ -7,121 +7,102 @@
 #include "log.h"
 #include "site.h"
 
+/* TODO: refactor to use roscha instead of unja */
+
 static bool
 images_walk(struct bstnode *node, void *data)
 {
 	struct image *image = node->value;
 
-	hashmap_insert(image->map, "source", image->url_image);
-	hashmap_insert(image->map, "date", image->datestr);
+	roscha_hmap_set_new(image->map, "source", (slice_whole(image->url_image)));
+	roscha_hmap_set_new(image->map, "date", (slice_whole(image->datestr)));
 	struct bstnode *prev = bstree_predecessor(node), 
 				   *next = bstree_successor(node);
 	char *url;
 	if (prev) {
 		url = ((struct image *)prev->value)->url;
-		hashmap_insert(image->map, "prev", url);
+		roscha_hmap_set_new(image->map, "prev", (slice_whole(url)));
 	}
 	if (next) {
 		url = ((struct image *)next->value)->url;
-		hashmap_insert(image->map, "next", url);
+		roscha_hmap_set_new(image->map, "next", (slice_whole(url)));
 	}
 
-	hashmap_insert(image->thumb, "link", image->url);
-	hashmap_insert(image->thumb, "source", image->url_thumb);
+	roscha_hmap_set_new(image->thumb, "link", (slice_whole(image->url)));
+	roscha_hmap_set_new(image->thumb, "source", (slice_whole(image->url_thumb)));
 
-	vector_push(image->album->thumbs, image->thumb);
+	roscha_vector_push(image->album->thumbs, image->thumb);
 
 	return true;
 }
 
-static struct hashmap *
-years_push_new_year(struct vector *years, char *yearstr)
+static struct roscha_object *
+years_push_new_year(struct roscha_object *years, char *yearstr)
 {
-	struct hashmap *year = hashmap_new_with_cap(4);
-	struct vector *albums = vector_new(8);
-	hashmap_insert(year, "name", yearstr);
-	hashmap_insert(year, "albums", albums);
-	vector_push(years, year);
+	struct roscha_object *year = roscha_object_new(hmap_new_with_cap(8));
+	struct roscha_object *albums = roscha_object_new(vector_new_with_cap(8));
+	roscha_hmap_set_new(year, "name", (slice_whole(yearstr)));
+	roscha_hmap_set(year, "albums", albums);
+	roscha_vector_push(years, year);
 
 	return year;
 }
 
 static void
-years_push_album(struct vector *years, struct album *album)
+years_push_album(struct roscha_object *years, struct album *album)
 {
-	struct hashmap *year;
-	struct vector *albums;
-	if (years->size == 0) {
+	struct roscha_object *year;
+	struct roscha_object *albums;
+	if (years->vector->len == 0) {
 		year = years_push_new_year(years, album->year);
 	} else {
-		year = years->values[years->size - 1];
-		char *yearstr = hashmap_get(year, "name");
-		if (strcmp(yearstr, album->year)) {
+		year = years->vector->values[years->vector->len - 1];
+		struct roscha_object *yearval = roscha_hmap_get(year, "name");
+		if (strcmp(yearval->slice.str, album->year)) {
 			year = years_push_new_year(years, album->year);
 		}
 	}
-	albums = hashmap_get(year, "albums");
-	vector_push(albums, album->map);
-}
-
-static void
-year_walk(const void *k, void *v)
-{
-	if (!strcmp(k, "albums")) {
-		struct vector *albums = v;
-		vector_free(albums);
-	}
-}
-
-static void
-years_destroy(struct vector *years)
-{
-	for (size_t i = 0; i < years->size; i++) {
-		struct hashmap *year = years->values[i];
-		hashmap_walk(year, year_walk);
-		hashmap_free(year);
-	}
-	vector_free(years);
+	albums = roscha_hmap_get(year, "albums");
+	roscha_vector_push(albums, album->map);
 }
 
 bool
 render_set_album_vars(struct render *r, struct album *album)
 {
 
-	hashmap_insert(album->map, "title", album->config->title);
-	hashmap_insert(album->map, "desc", album->config->desc);
-	hashmap_insert(album->map, "link", album->url);
-	hashmap_insert(album->map, "date", (char *)album->datestr);
-	hashmap_insert(album->map, "year", album->year);
+	if (album->config->title) {
+		roscha_hmap_set_new(album->map, "title",
+				(slice_whole(album->config->title)));
+	}
+	if (album->config->desc) {
+		roscha_hmap_set_new(album->map, "desc",
+				(slice_whole(album->config->desc)));
+	}
+	roscha_hmap_set_new(album->map, "link", (slice_whole(album->url)));
+	roscha_hmap_set_new(album->map, "date", (slice_whole(album->datestr)));
+	roscha_hmap_set_new(album->map, "year", (slice_whole(album->year)));
 
 	bstree_inorder_walk(album->images->root, images_walk, NULL);
 
-	for (uint32_t i = 0; 
-			i < album->thumbs->size && i < album->previews->cap; i++) {
-		vector_push(album->previews, album->thumbs->values[i]);
-	}
-
-	hashmap_insert(album->map, "thumbs", album->thumbs);
-	hashmap_insert(album->map, "previews", album->previews);
+	roscha_hmap_set(album->map, "thumbs", album->thumbs);
 
 	years_push_album(r->years, album);
-	vector_push(r->albums, album->map);
+	roscha_vector_push(r->albums, album->map);
 
 	/*
 	 * The common vars for the images in this album; used by both the album
 	 * template and the image template.
 	 */
-	hashmap_insert(r->common_vars, "album", album->map);
+	roscha_object_unref(roscha_hmap_set(r->env->vars, "album", album->map));
 
 	return true;
 }
 
 static bool
-render(struct env *env, const char *tmpl, const char *opath, 
-		struct hashmap *vars)
+render(struct roscha_env *env, const char *tmpl, const char *opath)
 {
 	bool ok = true;
-	char *output = template(env, tmpl, vars);
+	sds output = roscha_env_render(env, tmpl);
 	size_t outlen = strlen(output);
 	FILE *f = fopen(opath, "w");
 	if (fwrite(output, 1, outlen, f) != outlen) {
@@ -129,7 +110,7 @@ render(struct env *env, const char *tmpl, const char *opath,
 		log_printl_errno(LOG_FATAL, "Can't write %s", opath);
 	}
 	fclose(f);
-	free(output);
+	sdsfree(output);
 	return ok;
 }
 
@@ -147,11 +128,11 @@ render_make_index(struct render *r, const char *path)
 
 	if (r->dry_run) goto done;
 
-	hashmap_insert(r->common_vars, "years", r->years);
-	hashmap_insert(r->common_vars, "albums", r->years);
-	ok = render(r->env, "index.html", path, r->common_vars);
-	hashmap_remove(r->common_vars, "years");
-	hashmap_remove(r->common_vars, "albums");
+	roscha_hmap_set(r->env->vars, "years", r->years);
+	roscha_hmap_set(r->env->vars, "albums", r->years);
+	ok = render(r->env, "index.html", path);
+	roscha_hmap_unset(r->env->vars, "years");
+	roscha_hmap_unset(r->env->vars, "albums");
 
 	setdatetime(path, &r->modtime);
 done:
@@ -172,7 +153,7 @@ render_make_album(struct render *r, const char *path, const struct album *album)
 
 	if (r->dry_run) goto done;
 
-	ok = render(r->env, "album.html", path, r->common_vars);
+	ok = render(r->env, "album.html", path);
 
 	setdatetime(path, &r->modtime);
 done:
@@ -188,9 +169,9 @@ render_make_image(struct render *r, const char *path, const struct image *image)
 
 	if (r->dry_run) goto done;
 
-	hashmap_insert(r->common_vars, "image", image->map);
-	ok = render(r->env, "image.html", path, r->common_vars);
-	hashmap_remove(r->common_vars, "image");
+	roscha_hmap_set(r->env->vars, "image", image->map);
+	ok = render(r->env, "image.html", path);
+	roscha_hmap_unset(r->env->vars, "image");
 
 	setdatetime(path, &r->modtime);
 done:
@@ -217,17 +198,19 @@ render_init(struct render *r, const char *root, struct site_config *conf,
 
 	if (r->dry_run) goto cleanup;
 
-	r->env = env_new(tmplpath);
-	if (r->env == NULL) {
-		log_printl_errno(LOG_FATAL, "Couldn't initialize template engine");
+	r->env = roscha_env_new();
+	bool ok =  roscha_env_load_dir(r->env, tmplpath);
+	if (!ok) {
+		struct vector *errors = roscha_env_check_errors(r->env);
+		log_printl(LOG_FATAL, "Couldn't initialize template engine: %s",
+				errors->values[0]);
 		return false;
 	}
-	r->years = vector_new(8);
-	r->albums = vector_new(64);
+	r->years = roscha_object_new(vector_new_with_cap(8));
+	r->albums = roscha_object_new(vector_new_with_cap(64));
 
-	r->common_vars = hashmap_new_with_cap(16);
-	hashmap_insert(r->common_vars, "title", conf->title);
-	hashmap_insert(r->common_vars, "index", conf->base_url);
+	roscha_hmap_set_new(r->env->vars, "title", (slice_whole(conf->title)));
+	roscha_hmap_set_new(r->env->vars, "index", (slice_whole(conf->base_url)));
 
 	//bstree_inorder_walk(albums->root, albums_walk, (void *)r);
 
@@ -239,8 +222,7 @@ cleanup:
 void
 render_deinit(struct render *r)
 {
-	env_free(r->env);
-	years_destroy(r->years);
-	vector_free(r->albums);
-	hashmap_free(r->common_vars);
+	roscha_env_destroy(r->env);
+	roscha_object_unref(r->years);
+	roscha_object_unref(r->albums);
 }
diff --git a/src/revela.c b/src/revela.c
index 89a7a7a..32867c6 100644
--- a/src/revela.c
+++ b/src/revela.c
@@ -9,7 +9,6 @@
 #include "site.h"
 #include "config.h"
 #include "bstree.h"
-#include "template.h"
 
 static const char *usage =
 	"Usage: %s [options] [-i <input dir>] -o <output dir>\n";
diff --git a/src/site.c b/src/site.c
index 2d3922b..058da13 100644
--- a/src/site.c
+++ b/src/site.c
@@ -8,7 +8,7 @@
 
 #include "fs.h"
 #include "log.h"
-#include "hashmap.h"
+#include "hmap.h"
 
 /* TODO: handle error cases for paths that are too long */
 
@@ -154,7 +154,7 @@ images_walk(struct bstnode *node, void *data)
 	}
 
 	joinpathb(htmlpath, image->dst, index_html);
-	hashmap_insert(image->album->preserved, base, (char *)base);
+	hmap_set(image->album->preserved, base, (char *)base);
 
 	int isupdate = file_is_uptodate(htmlpath, &site->render.modtime);
 	if (isupdate == -1) return false;
@@ -215,7 +215,7 @@ albums_walk(struct bstnode *node, void *data)
 	struct stat dstat;
 	if (!nmkdir(album->slug, &dstat, site->dry_run)) return false;
 
-	hashmap_insert(site->album_dirs, album->slug, (char *)album->slug);
+	hmap_set(site->album_dirs, album->slug, (char *)album->slug);
 	if (!site->dry_run) {
 		if (!render_set_album_vars(&site->render, album)) return false;
 
@@ -226,7 +226,7 @@ albums_walk(struct bstnode *node, void *data)
 		return false;
 	}
 
-	hashmap_insert(album->preserved, index_html, (char *)index_html);
+	hmap_set(album->preserved, index_html, (char *)index_html);
 	ssize_t deleted = rmextra(album->slug, album->preserved, prerm_imagedir,
 			album, site->dry_run);
 	if (deleted < 0) {
@@ -321,6 +321,8 @@ site_build(struct site *site)
 {
 	struct stat dstat;
 	char staticp[PATH_MAX];
+	char startwd[PATH_MAX];
+	getcwd(startwd, PATH_MAX);
 
 	if (!nmkdir(site->output_dir, &dstat, false)) return false;
 
@@ -335,7 +337,7 @@ site_build(struct site *site)
 	}
 
 	if (!render_make_index(&site->render, index_html)) return false;
-	hashmap_insert(site->album_dirs, index_html, (char *)index_html);
+	hmap_set(site->album_dirs, index_html, (char *)index_html);
 
 	joinpathb(staticp, site->root_dir, STATICDIR);
 	if (stat(staticp, &dstat)) {
@@ -354,7 +356,7 @@ site_build(struct site *site)
 		return false;
 	}
 
-	chdir(site->root_dir);
+	chdir(startwd);
 	return true;
 }
 
@@ -391,9 +393,11 @@ site_init(struct site *site)
 	site->rel_content_dir = strlen(site->root_dir) + 1;
 	InitializeMagick(NULL);
 	site->wand = NewMagickWand();
-	site->album_dirs = hashmap_new();
+	site->album_dirs = hmap_new();
 	site->render.dry_run = site->dry_run;
 
+	roscha_init();
+
 	return true;
 }
 
@@ -409,7 +413,9 @@ site_deinit(struct site *site)
 		DestroyMagick();
 	}
 	if (!site->dry_run) {
-		hashmap_free(site->album_dirs);
+		hmap_free(site->album_dirs);
 		render_deinit(&site->render);
 	}
+
+	roscha_deinit();
 }
-- 
cgit v1.2.3