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