Mercurial
annotate mrjunejune/template_renderer.c @ 265:056790c4fb0d
add role-aware Epi assistant prompts
Add verified June knowledge, guest/member/admin Copilot profiles, profile-isolated session recovery, animated Epi greetings, and a single authoritative runtime config workflow for inference.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 07 Aug 2026 10:50:30 -0700 |
| parents | 04fee26ecce0 |
| children |
| rev | line source |
|---|---|
|
264
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
1 /* |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
2 * template_renderer.c — site-owned HTML template renderer for mrjunejune. |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
3 * |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
4 * Expands one level of {{/path}} include tokens found in HTML templates. |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
5 * File I/O is done with standard C fopen/fread so that tests can point |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
6 * the renderer at any root without depending on Seobeo server state. |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
7 */ |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
8 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
9 #include "mrjunejune/template_renderer.h" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
10 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
11 #include "dowa/dowa.h" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
12 #include "seobeo/seobeo.h" |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
13 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
14 #include <stdio.h> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
15 #include <stdlib.h> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
16 #include <string.h> |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
17 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
18 /* Default matches the path Seobeo_Web_Server_Start_On receives in main.c. */ |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
19 static char g_src_root[512] = "mrjunejune/src"; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
20 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
21 void Mjj_Template_Renderer_Init(const char *src_root) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
22 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
23 if (!src_root || src_root[0] == '\0') |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
24 return; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
25 strncpy(g_src_root, src_root, sizeof(g_src_root) - 1); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
26 g_src_root[sizeof(g_src_root) - 1] = '\0'; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
27 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
28 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
29 /* Load a file using the renderer's own root; caller must free() result. */ |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
30 static char *renderer_load_file(const char *rel_path, size_t *p_size) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
31 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
32 if (!rel_path) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
33 return NULL; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
34 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
35 char full_path[1024]; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
36 /* rel_path already starts with '/' when produced by canonical markers |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
37 (e.g. "/parts/base_head.html"), so concatenate directly. */ |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
38 if (rel_path[0] == '/') |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
39 snprintf(full_path, sizeof(full_path), "%s%s", g_src_root, rel_path); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
40 else |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
41 snprintf(full_path, sizeof(full_path), "%s/%s", g_src_root, rel_path); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
42 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
43 FILE *f = fopen(full_path, "rb"); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
44 if (!f) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
45 return NULL; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
46 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
47 fseek(f, 0, SEEK_END); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
48 long sz = ftell(f); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
49 fseek(f, 0, SEEK_SET); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
50 if (sz < 0) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
51 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
52 fclose(f); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
53 return NULL; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
54 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
55 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
56 char *buf = (char *)malloc((size_t)sz + 1); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
57 if (!buf) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
58 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
59 fclose(f); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
60 return NULL; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
61 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
62 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
63 size_t n = fread(buf, 1, (size_t)sz, f); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
64 fclose(f); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
65 buf[n] = '\0'; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
66 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
67 if (p_size) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
68 *p_size = n; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
69 return buf; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
70 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
71 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
72 /* Write `len` bytes of `src` to out starting at *p_offset, respecting cap. |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
73 Returns FALSE and does a best-effort NUL-terminate on overflow. */ |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
74 static boolean safe_append( |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
75 char *out, size_t cap, size_t *p_offset, |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
76 const char *src, size_t len) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
77 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
78 if (len == 0) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
79 return TRUE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
80 if (*p_offset + len >= cap) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
81 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
82 /* Partial write then NUL-terminate. */ |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
83 size_t avail = (cap > *p_offset + 1) ? (cap - *p_offset - 1) : 0; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
84 if (avail > 0) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
85 memcpy(out + *p_offset, src, avail); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
86 out[cap - 1] = '\0'; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
87 return FALSE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
88 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
89 memcpy(out + *p_offset, src, len); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
90 *p_offset += len; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
91 return TRUE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
92 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
93 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
94 boolean Mjj_Template_Render( |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
95 char *out, size_t cap, const char *tmpl, Dowa_Arena *arena) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
96 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
97 if (!out || cap == 0) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
98 return FALSE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
99 out[0] = '\0'; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
100 if (!tmpl) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
101 return FALSE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
102 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
103 size_t offset = 0; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
104 const char *cursor = tmpl; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
105 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
106 while (1) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
107 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
108 const char *open = strstr(cursor, "{{"); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
109 if (!open) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
110 break; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
111 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
112 const char *close = strstr(open + 2, "}}"); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
113 if (!close) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
114 break; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
115 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
116 /* Copy text before the token. */ |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
117 size_t lead = (size_t)(open - cursor); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
118 if (!safe_append(out, cap, &offset, cursor, lead)) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
119 return FALSE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
120 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
121 /* Extract include path between {{ and }}. */ |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
122 size_t name_len = (size_t)(close - (open + 2)); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
123 char *include_name = (char *)Dowa_Arena_Allocate(arena, name_len + 1); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
124 if (!include_name) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
125 return FALSE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
126 memcpy(include_name, open + 2, name_len); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
127 include_name[name_len] = '\0'; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
128 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
129 /* Load and inline the included file; skip silently if missing. */ |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
130 size_t inc_size = 0; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
131 char *inc = renderer_load_file(include_name, &inc_size); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
132 Seobeo_Log(SEOBEO_DEBUG, |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
133 "[TEMPLATE] include '%s' -> %s (size=%zu)\n", |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
134 include_name, inc ? "OK" : "MISSING", inc_size); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
135 if (inc) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
136 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
137 boolean ok = safe_append(out, cap, &offset, inc, inc_size); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
138 free(inc); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
139 if (!ok) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
140 return FALSE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
141 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
142 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
143 cursor = close + 2; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
144 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
145 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
146 /* Copy the tail (after the last token, or the whole string if no tokens). */ |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
147 size_t tail = strlen(cursor); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
148 if (!safe_append(out, cap, &offset, cursor, tail)) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
149 return FALSE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
150 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
151 out[offset] = '\0'; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
152 return TRUE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
153 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
154 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
155 boolean Mjj_Template_Render_File( |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
156 char *out, size_t cap, const char *path, Dowa_Arena *arena) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
157 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
158 if (!out || cap == 0) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
159 return FALSE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
160 out[0] = '\0'; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
161 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
162 Seobeo_Log(SEOBEO_DEBUG, "[TEMPLATE] loading file '%s'\n", path); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
163 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
164 size_t file_size = 0; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
165 char *tmpl = renderer_load_file(path, &file_size); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
166 if (!tmpl) |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
167 { |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
168 Seobeo_Log(SEOBEO_DEBUG, "[TEMPLATE] file '%s' not found\n", path); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
169 return FALSE; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
170 } |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
171 |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
172 boolean ok = Mjj_Template_Render(out, cap, tmpl, arena); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
173 free(tmpl); |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
174 return ok; |
|
04fee26ecce0
add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
175 } |