Mercurial > sci
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 } |