comparison 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
comparison
equal deleted inserted replaced
27:dae2de19ca5d 28:4c16bb25e4f1
1 #include <assert.h>
2 #include <errno.h>
3 #include <limits.h>
4 #include <string.h>
5
6 #include <duktape.h>
7
8 #include "log.h"
9 #include "theme.h"
10 #include "util.h"
11
12 struct theme {
13 char base[PATH_MAX];
14 duk_context *ctx;
15 };
16
17 static char *
18 render(struct theme *t, const char *json, const char *function)
19 {
20 char *ret = NULL;
21
22 duk_get_global_string(t->ctx, function);
23
24 if (!duk_is_callable(t->ctx, -1)) {
25 duk_pop(t->ctx);
26 return NULL;
27 }
28
29 duk_push_string(t->ctx, json);
30 duk_json_decode(t->ctx, -1);
31
32 if (duk_pcall(t->ctx, 1) != 0) {
33 log_warn("theme: %s", duk_safe_to_string(t->ctx, -1));
34 } else if (duk_is_string(t->ctx, -1))
35 ret = util_strdup(duk_get_string(t->ctx, -1));
36
37 duk_pop_n(t->ctx, 1);
38
39 /*
40 * For convenience, otherwise all callers have to check for non-NULL
41 * after calling the function.
42 */
43 if (!ret)
44 ret = util_strdup("");
45
46 return ret;
47 }
48
49 const char *
50 theme_path(struct theme *t, const char *filename)
51 {
52 assert(filename);
53
54 /* Build path to the template file. */
55 static _Thread_local char path[PATH_MAX];
56
57 snprintf(path, sizeof (path), "%s/%s", t->base, filename);
58
59 return path;
60 }
61
62 struct theme *
63 theme_open(const char *directory)
64 {
65 assert(directory);
66
67 struct theme *t;
68 char themefile[PATH_MAX], *data;
69
70 t = util_calloc(1, sizeof (*t));
71 t->ctx = duk_create_heap_default();
72 util_strlcpy(t->base, directory, sizeof (t->base));
73
74 /* Open theme.js in the directory. */
75 snprintf(themefile, sizeof (themefile), "%s/theme.js", t->base);
76
77 if (!(data = util_read(themefile)))
78 log_warn("theme: %s: %s", themefile, strerror(errno));
79 else {
80 if (duk_peval_string(t->ctx, data) != 0)
81 log_warn("theme: %s", duk_safe_to_string(t->ctx, -1));
82
83 duk_pop(t->ctx);
84 }
85
86 return t;
87 }
88
89 char *
90 theme_render_index(struct theme *t, const char *json)
91 {
92 assert(t);
93 assert(json);
94
95 return render(t, json, "index");
96 }
97
98 void
99 theme_free(struct theme *t)
100 {
101 assert(t);
102
103 duk_destroy_heap(t->ctx);
104 }