Mercurial > sci
view scid/theme.c @ 28:4c16bb25e4f1
scid: implement themes in javascript
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 04 Aug 2022 06:09:54 +0200 |
parents | |
children | 695637f1d8a7 |
line wrap: on
line source
#include <assert.h> #include <errno.h> #include <limits.h> #include <string.h> #include <duktape.h> #include "log.h" #include "theme.h" #include "util.h" struct theme { char base[PATH_MAX]; duk_context *ctx; }; static char * render(struct theme *t, const char *json, const char *function) { char *ret = NULL; duk_get_global_string(t->ctx, function); if (!duk_is_callable(t->ctx, -1)) { duk_pop(t->ctx); return NULL; } duk_push_string(t->ctx, json); duk_json_decode(t->ctx, -1); if (duk_pcall(t->ctx, 1) != 0) { log_warn("theme: %s", duk_safe_to_string(t->ctx, -1)); } else if (duk_is_string(t->ctx, -1)) ret = util_strdup(duk_get_string(t->ctx, -1)); duk_pop_n(t->ctx, 1); /* * For convenience, otherwise all callers have to check for non-NULL * after calling the function. */ if (!ret) ret = util_strdup(""); return ret; } const char * theme_path(struct theme *t, const char *filename) { assert(filename); /* Build path to the template file. */ static _Thread_local char path[PATH_MAX]; snprintf(path, sizeof (path), "%s/%s", t->base, filename); return path; } struct theme * theme_open(const char *directory) { assert(directory); struct theme *t; char themefile[PATH_MAX], *data; t = util_calloc(1, sizeof (*t)); t->ctx = duk_create_heap_default(); util_strlcpy(t->base, directory, sizeof (t->base)); /* Open theme.js in the directory. */ snprintf(themefile, sizeof (themefile), "%s/theme.js", t->base); if (!(data = util_read(themefile))) log_warn("theme: %s: %s", themefile, strerror(errno)); else { if (duk_peval_string(t->ctx, data) != 0) log_warn("theme: %s", duk_safe_to_string(t->ctx, -1)); duk_pop(t->ctx); } return t; } char * theme_render_index(struct theme *t, const char *json) { assert(t); assert(json); return render(t, json, "index"); } void theme_free(struct theme *t) { assert(t); duk_destroy_heap(t->ctx); }