annotate scid/page.c @ 26:7e10cace67a3

scid: add basic mustache support
author David Demelier <markand@malikania.fr>
date Tue, 02 Aug 2022 13:24:13 +0200
parents 600204c31bf0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * page.c -- page renderer
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2021 David Demelier <markand@malikania.fr>
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
26
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
19 #include <sys/stat.h>
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
20 #include <assert.h>
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
21 #include <errno.h>
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
22 #include <fcntl.h>
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
23 #include <stdint.h>
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
24 #include <stdio.h>
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
25 #include <stdlib.h>
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
26 #include <string.h>
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
27 #include <unistd.h>
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
28
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
29 #include <mustache.h>
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
30
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
31 #include "log.h"
2
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 #include "page.h"
26
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
33 #include "scid.h"
2
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 #include "util.h"
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
35
26
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
36 static void
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
37 parse_error(int code, const char *msg, unsigned int line, unsigned int col, void *data)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
38 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
39 (void)code;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
40
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
41 const char *path = data;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
42
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
43 log_warn("page: %s:%u:%u:%s", path, line, col, msg);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
44 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
45
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
46 static int
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
47 out_verbatim(const char *output, size_t size, void *data)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
48 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
49 FILE *fp = data;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
50
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
51 if (fwrite(output, 1, size, fp) != size)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
52 return -1;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
53
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
54 return 0;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
55 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
56
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
57 static int
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
58 out_escaped(const char *output, size_t size, void *data)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
59 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
60 FILE *fp = data;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
61
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
62 for (size_t i = 0; i < size; ++i) {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
63 switch (output[i]) {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
64 case '"':
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
65 if (out_verbatim("&quot;", 6, fp) < 0)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
66 return -1;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
67 break;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
68 case '&':
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
69 if (out_verbatim("&amp;", 5, fp) < 0)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
70 return -1;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
71 break;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
72 case '<':
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
73 if (out_verbatim("&lt;", 4, fp) < 0)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
74 return -1;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
75 break;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
76 case '>':
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
77 if (out_verbatim("&gt;", 4, fp) < 0)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
78 return -1;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
79 break;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
80 default:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
81 if (out_verbatim(&output[i], 1, fp) <0)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
82 return -1;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
83 break;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
84 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
85 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
86
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
87 return 0;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
88 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
89
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
90 static inline int
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
91 out_int(FILE *fp, intmax_t val)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
92 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
93 char buf[64] = {0};
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
94
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
95 snprintf(buf, sizeof (buf), "%jd", val);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
96
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
97 return out_verbatim(buf, strlen(buf), fp);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
98 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
99
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
100 static inline int
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
101 out_double(FILE *fp, double val)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
102 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
103 char buf[64] = {0};
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
104
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
105 snprintf(buf, sizeof (buf), "%f", val);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
106
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
107 return out_verbatim(buf, strlen(buf), fp);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
108 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
109
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
110 static int
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
111 dump(void *node, int (*outputter)(const char *, size_t, void *), void *rdata, void *pdata)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
112 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
113 (void)pdata;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
114
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
115 FILE *fp = rdata;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
116 const json_t *value = node;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
117
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
118 switch (json_typeof(value)) {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
119 case JSON_OBJECT:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
120 case JSON_ARRAY:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
121 /* This indicates a document construction error. */
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
122 // TODO: change to error log.
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
123 abort();
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
124 break;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
125 case JSON_STRING:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
126 return outputter(json_string_value(value), json_string_length(value), fp);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
127 case JSON_INTEGER:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
128 return out_int(fp, json_integer_value(value));
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
129 case JSON_REAL:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
130 return out_double(fp, json_real_value(value));
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
131 case JSON_TRUE:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
132 return out_verbatim("true", 4, fp);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
133 case JSON_FALSE:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
134 return out_verbatim("false", 5, fp);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
135 default:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
136 break;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
137 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
138
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
139 return 0;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
140 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
141
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
142 static void *
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
143 get_root(void *pdata)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
144 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
145 return pdata;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
146 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
147
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
148 static void *
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
149 get_child_by_name(void *node, const char *name, size_t size, void *pdata)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
150 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
151 (void)pdata;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
152
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
153 json_t *value = node;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
154
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
155 #if 1
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
156 printf("-> Seeking name '%.*s'\n", (int)size, name);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
157 printf("-> Type of node: %d (%p)\n", json_typeof(value), value);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
158 #endif
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
159
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
160 if (json_is_object(value))
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
161 return json_object_getn(node, name, size);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
162
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
163 return NULL;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
164 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
165
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
166 static void *
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
167 get_child_by_index(void *node, unsigned int index, void *pdata)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
168 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
169 (void)pdata;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
170
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
171 json_t *value = node;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
172
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
173 #if 1
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
174 printf("-> Seeking index '%u'\n", index);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
175 printf("-> Type of node: %d (%p)\n", json_typeof(value), value);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
176 #endif
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
177
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
178 if (json_is_array(value))
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
179 return json_array_get(node, index);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
180
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
181 return NULL;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
182 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
183
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
184 static MUSTACHE_TEMPLATE *
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
185 get_partial(const char *name, size_t size, void *pdata)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
186 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
187 (void)name;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
188 (void)size;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
189 (void)pdata;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
190
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
191 return NULL;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
192 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
193
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
194 static char *
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
195 readall(const char *file)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
196 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
197 int fd;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
198 char *ret = NULL;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
199 struct stat st;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
200
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
201 if ((fd = open(file, O_RDONLY)) < 0)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
202 return NULL;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
203 if (fstat(fd, &st) < 0)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
204 goto exit;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
205 if (!(ret = calloc(1, st.st_size + 1)))
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
206 goto exit;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
207 if (read(fd, ret, st.st_size) != st.st_size) {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
208 free(ret);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
209 ret = NULL;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
210 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
211
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
212 exit:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
213 close(fd);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
214
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
215 return ret;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
216 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
217
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
218 static int
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
219 process(const char *path, const char *input, FILE *fp, json_t *doc)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
220 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
221 MUSTACHE_PARSER parser = {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
222 .parse_error = parse_error
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
223 };
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
224 MUSTACHE_RENDERER rdr = {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
225 .out_verbatim = out_verbatim,
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
226 .out_escaped = out_escaped
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
227 };
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
228 MUSTACHE_DATAPROVIDER pv = {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
229 .dump = dump,
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
230 .get_root = get_root,
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
231 .get_child_by_name = get_child_by_name,
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
232 .get_child_by_index = get_child_by_index,
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
233 .get_partial = get_partial
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
234 };
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
235 MUSTACHE_TEMPLATE *tmpl;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
236 int status;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
237
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
238 if (!(tmpl = mustache_compile(input, strlen(input), &parser, (void *)path, 0)))
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
239 return -1;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
240
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
241 status = mustache_process(tmpl, &rdr, fp, &pv, doc);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
242 mustache_release(tmpl);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
243
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
244 return status ? -1 : 0;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
245 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
246
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
247 char *
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
248 templatize(const char *path, json_t *doc)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
249 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
250 assert(path);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
251
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
252 char *in = NULL, *out = NULL;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
253 size_t outsz = 0;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
254 FILE *fp;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
255
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
256 if (!(fp = open_memstream(&out, &outsz)))
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
257 goto exit;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
258 if (!(in = readall(path)))
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
259 goto exit;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
260
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
261 /* Process template but don't return a partially written file. */
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
262 if (process(path, in, fp, doc) < 0) {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
263 fclose(fp);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
264 free(out);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
265 fp = NULL;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
266 out = NULL;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
267 errno = EINVAL;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
268 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
269
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
270 exit:
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
271 if (!out)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
272 log_warn("page: %s: %s", path, strerror(errno));
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
273 if (fp)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
274 fclose(fp);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
275
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
276 free(in);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
277 json_decref(doc);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
278
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
279 return out;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
280 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
281
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
282 static void
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
283 render(struct kreq *req, const char *path, json_t *doc)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
284 {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
285 char *content;
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
286
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
287 if (!(content = templatize(path, doc)))
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
288 log_warn("page: unable to templatize: %s", strerror(errno));
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
289 if (doc)
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
290 json_decref(doc);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
291
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
292 khttp_printf(req, "%s", content);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
293
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
294 free(content);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
295 }
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
296
2
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
297 void
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 page(struct kreq *req,
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
299 enum khttp status,
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 enum kmime mime,
26
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
301 const char *path,
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
302 json_t *doc)
2
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
303 {
26
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
304 assert(req);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
305 assert(!path || (path && doc));
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
306
2
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
307 khttp_head(req, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[mime]);
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
308 khttp_head(req, kresps[KRESP_STATUS], "%s", khttps[status]);
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 khttp_body(req);
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
310
26
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
311 if (path) {
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
312 printf("document is: [%s]\n", json_dumps(doc, JSON_INDENT(2)));
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
313 /* TODO: add title in the header. */
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
314 render(req, scid_theme_path("fragments/header.html"), NULL);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
315 render(req, scid_theme_path(path), doc);
7e10cace67a3 scid: add basic mustache support
David Demelier <markand@malikania.fr>
parents: 18
diff changeset
316 render(req, scid_theme_path("fragments/footer.html"), NULL);
2
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
317 }
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
318
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
319 khttp_free(req);
5fa3d2f479b2 sci: initial upload support
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 }