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