Mercurial > sci
diff scid/theme.c @ 30:43333d18e4b8
scid: document theme
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 04 Aug 2022 14:54:43 +0200 |
parents | 695637f1d8a7 |
children | 081e1c258e64 |
line wrap: on
line diff
--- a/scid/theme.c Thu Aug 04 14:13:58 2022 +0200 +++ b/scid/theme.c Thu Aug 04 14:54:43 2022 +0200 @@ -1,3 +1,21 @@ +/* + * theme.c -- theme management + * + * Copyright (c) 2021 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #include <assert.h> #include <errno.h> #include <limits.h> @@ -14,10 +32,9 @@ #define SIGNATURE DUK_HIDDEN_SYMBOL("File") -struct theme { - char base[PATH_MAX]; +static struct { duk_context *ctx; -}; +} theme; /* {{{ mustache support */ @@ -198,7 +215,7 @@ }; MUSTACHE_TEMPLATE *tmpl; int status; - + if (!(tmpl = mustache_compile(input, strlen(input), &parser, (void *)path, 0))) return -1; @@ -241,7 +258,7 @@ if (json && !(doc = json_loads(json, 0, &err))) return duk_error(ctx, DUK_ERR_ERROR, "%d:%d:%s", err.line, err.column, err.text); - mch_templatize(fp, theme_path(scid.theme, path), doc); + mch_templatize(fp, theme_path(path), doc); if (doc) json_decref(doc); @@ -266,118 +283,99 @@ /* }}} */ static char * -call(struct theme *t, json_t *json, const char *function) +call(const json_t *json, const char *function) { - char *out = NULL, *dump = NULL; + char *out = NULL, *dump; size_t outsz = 0; - FILE *fp = NULL; - int nargs = 1; + FILE *fp; - duk_get_global_string(t->ctx, function); + duk_get_global_string(theme.ctx, function); - if (!duk_is_callable(t->ctx, -1)) - goto over; - if (!(fp = open_memstream(&out, &outsz))) - goto over; - - duk_push_pointer(t->ctx, fp); + if (duk_is_callable(theme.ctx, -1)) { + fp = util_open_memstream(&out, &outsz); + dump = util_json_dump(json); - if (json && (dump = json_dumps(json, JSON_COMPACT))) { - duk_push_string(t->ctx, dump); - duk_json_decode(t->ctx, -1); - nargs++; - } + duk_push_pointer(theme.ctx, fp); + duk_push_string(theme.ctx, dump); + duk_json_decode(theme.ctx, -1); - if (duk_pcall(t->ctx, nargs) != 0) - log_warn("theme: %s", duk_safe_to_string(t->ctx, -1)); + if (duk_pcall(theme.ctx, 2) != 0) + log_warn("theme: %s", duk_safe_to_string(theme.ctx, -1)); -over: - duk_pop(t->ctx); + duk_pop(theme.ctx); + fclose(fp); + free(dump); + } else + duk_pop(theme.ctx); - /* - * For convenience, otherwise all callers have to check for non-NULL - * after calling the function. - */ - free(dump); - - if (fp) - fclose(fp); if (!out) out = util_strdup(""); return out; } +void +theme_open(const char *directory) +{ + assert(directory); + + const char *path; + char *data; + + theme.ctx = duk_create_heap_default(); + path = theme_path("theme.js"); + + if (!(data = util_read(path))) + log_warn("theme: %s: %s", path, strerror(errno)); + else { + if (duk_peval_string(theme.ctx, data) != 0) + log_warn("theme: %s", duk_safe_to_string(theme.ctx, -1)); + + duk_pop(theme.ctx); + duk_push_object(theme.ctx); + duk_put_function_list(theme.ctx, -1, functions); + duk_put_global_string(theme.ctx, "Scid"); + free(data); + } +} + const char * -theme_path(struct theme *t, const char *filename) +theme_path(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); + snprintf(path, sizeof (path), "%s/%s", scid.themedir, filename); return path; } -struct theme * -theme_open(const char *directory) +char * +theme_page_index(const json_t *json) { - 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); + assert(json); - 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); - duk_push_object(t->ctx); - duk_put_function_list(t->ctx, -1, functions); - duk_put_global_string(t->ctx, "Scid"); - free(data); - } - - return t; + return call(json, "onPageIndex"); } char * -theme_page_index(struct theme *t, json_t *json) -{ - assert(t); - - return call(t, json, "onPageIndex"); -} - -char * -theme_page_status(struct theme *t, enum khttp status) +theme_page_status(enum khttp status) { - assert(t); - - (void)t; - (void)status; + json_t *doc; + char *ret; -#if 0 - return call(t, json, "onPageStatus"); -#endif - return "ERROR"; + doc = util_json_pack("{si}", "status", status); + ret = call(doc, "onPageStatus"); + + json_decref(doc); + + return ret; } void -theme_free(struct theme *t) +theme_free(void) { - assert(t); - - duk_destroy_heap(t->ctx); + duk_destroy_heap(theme.ctx); }