File: | ctx.c |
Warning: | line 286, column 9 Value stored to 'ctx' is never read |
1 | /* |
2 | * blogc: A blog compiler. |
3 | * Copyright (C) 2014-2017 Rafael G. Martins <rafael@rafaelmartins.eng.br> |
4 | * |
5 | * This program can be distributed under the terms of the BSD License. |
6 | * See the file LICENSE. |
7 | */ |
8 | |
9 | #include <sys/stat.h> |
10 | #include <sys/types.h> |
11 | #include <dirent.h> |
12 | #include <libgen.h> |
13 | #include <time.h> |
14 | #include <stdlib.h> |
15 | #include <stdbool.h> |
16 | #include <string.h> |
17 | #include "../common/error.h" |
18 | #include "../common/file.h" |
19 | #include "../common/utils.h" |
20 | #include "atom.h" |
21 | #include "settings.h" |
22 | #include "exec.h" |
23 | #include "ctx.h" |
24 | |
25 | |
26 | bm_filectx_t* |
27 | bm_filectx_new(bm_ctx_t *ctx, const char *filename, const char *slug, |
28 | struct stat *st) |
29 | { |
30 | if (ctx == NULL((void*)0) || filename == NULL((void*)0)) |
31 | return NULL((void*)0); |
32 | |
33 | char *f = filename[0] == '/' ? bc_strdup(filename) : |
34 | bc_strdup_printf("%s/%s", ctx->root_dir, filename); |
35 | |
36 | bm_filectx_t *rv = bc_malloc(sizeof(bm_filectx_t)); |
37 | rv->path = f; |
38 | rv->short_path = bc_strdup(filename); |
39 | rv->slug = bc_strdup(slug); |
40 | |
41 | if (st == NULL((void*)0)) { |
42 | struct stat buf; |
43 | |
44 | if (0 != stat(f, &buf)) { |
45 | rv->tv_sec = 0; |
46 | rv->tv_nsec = 0; |
47 | rv->readable = false0; |
48 | return rv; |
49 | } |
50 | |
51 | st = &buf; |
52 | } |
53 | |
54 | // if it isn't NULL the file exists for sure |
55 | rv->tv_sec = st->st_mtim_tv_secst_mtim.tv_sec; |
56 | rv->tv_nsec = st->st_mtim_tv_nsecst_mtim.tv_nsec; |
57 | rv->readable = true1; |
58 | return rv; |
59 | } |
60 | |
61 | |
62 | bc_slist_t* |
63 | bm_filectx_new_r(bc_slist_t *l, bm_ctx_t *ctx, const char *filename) |
64 | { |
65 | if (ctx == NULL((void*)0) || filename == NULL((void*)0)) |
66 | return NULL((void*)0); |
67 | |
68 | char *f = filename[0] == '/' ? bc_strdup(filename) : |
69 | bc_strdup_printf("%s/%s", ctx->root_dir, filename); |
70 | |
71 | struct stat buf; |
72 | if (0 != stat(f, &buf)) { |
73 | free(f); |
74 | return l; |
75 | } |
76 | |
77 | if (S_ISDIR(buf.st_mode)((((buf.st_mode)) & 0170000) == (0040000))) { |
78 | DIR *dir = opendir(f); |
79 | if (dir == NULL((void*)0)) { |
80 | free(f); |
81 | return l; |
82 | } |
83 | |
84 | struct dirent *e; |
85 | while (NULL((void*)0) != (e = readdir(dir))) { |
86 | if ((0 == strcmp(e->d_name, ".")) || (0 == strcmp(e->d_name, ".."))) |
87 | continue; |
88 | char *tmp = bc_strdup_printf("%s/%s", filename, e->d_name); |
89 | l = bm_filectx_new_r(l, ctx, tmp); |
90 | free(tmp); |
91 | } |
92 | |
93 | closedir(dir); |
94 | free(f); |
95 | return l; |
96 | } |
97 | |
98 | l = bc_slist_append(l, bm_filectx_new(ctx, filename, NULL((void*)0), &buf)); |
99 | free(f); |
100 | return l; |
101 | } |
102 | |
103 | |
104 | bool_Bool |
105 | bm_filectx_changed(bm_filectx_t *ctx, time_t *tv_sec, long *tv_nsec) |
106 | { |
107 | if (ctx == NULL((void*)0)) |
108 | return false0; |
109 | |
110 | struct stat buf; |
111 | |
112 | if (0 == stat(ctx->path, &buf)) { |
113 | if (buf.st_mtim_tv_secst_mtim.tv_sec == ctx->tv_sec) { |
114 | if (buf.st_mtim_tv_nsecst_mtim.tv_nsec > ctx->tv_nsec) { |
115 | if (tv_sec != NULL((void*)0)) |
116 | *tv_sec = buf.st_mtim_tv_secst_mtim.tv_sec; |
117 | if (tv_nsec != NULL((void*)0)) |
118 | *tv_nsec = buf.st_mtim_tv_nsecst_mtim.tv_nsec; |
119 | return true1; |
120 | } |
121 | } |
122 | else if (buf.st_mtim_tv_secst_mtim.tv_sec > ctx->tv_sec) { |
123 | if (tv_sec != NULL((void*)0)) |
124 | *tv_sec = buf.st_mtim_tv_secst_mtim.tv_sec; |
125 | if (tv_nsec != NULL((void*)0)) |
126 | *tv_nsec = buf.st_mtim_tv_nsecst_mtim.tv_nsec; |
127 | return true1; |
128 | } |
129 | } |
130 | |
131 | return false0; |
132 | } |
133 | |
134 | |
135 | void |
136 | bm_filectx_reload(bm_filectx_t *ctx) |
137 | { |
138 | if (ctx == NULL((void*)0)) |
139 | return; |
140 | |
141 | time_t tv_sec; |
142 | long tv_nsec; |
143 | |
144 | if (!bm_filectx_changed(ctx, &tv_sec, &tv_nsec)) |
145 | return; |
146 | |
147 | ctx->tv_sec = tv_sec; |
148 | ctx->tv_nsec = tv_nsec; |
149 | ctx->readable = true1; |
150 | } |
151 | |
152 | |
153 | void |
154 | bm_filectx_free(bm_filectx_t *fctx) |
155 | { |
156 | if (fctx == NULL((void*)0)) |
157 | return; |
158 | free(fctx->path); |
159 | free(fctx->short_path); |
160 | free(fctx->slug); |
161 | free(fctx); |
162 | } |
163 | |
164 | |
165 | bm_ctx_t* |
166 | bm_ctx_new(bm_ctx_t *base, const char *settings_file, const char *argv0, |
167 | bc_error_t **err) |
168 | { |
169 | if (settings_file == NULL((void*)0) || err == NULL((void*)0) || *err != NULL((void*)0)) |
170 | return NULL((void*)0); |
171 | |
172 | size_t content_len; |
173 | char *content = bc_file_get_contents(settings_file, true1, &content_len, |
174 | err); |
175 | if (*err != NULL((void*)0)) |
176 | return NULL((void*)0); |
177 | |
178 | bm_settings_t *settings = bm_settings_parse(content, content_len, err); |
179 | if (*err != NULL((void*)0)) { |
180 | free(content); |
181 | return NULL((void*)0); |
182 | } |
183 | free(content); |
184 | |
185 | char *atom_template = bm_atom_deploy(settings, err); |
186 | if (*err != NULL((void*)0)) { |
187 | return NULL((void*)0); |
188 | } |
189 | |
190 | bm_ctx_t *rv = NULL((void*)0); |
191 | if (base == NULL((void*)0)) { |
192 | rv = bc_malloc(sizeof(bm_ctx_t)); |
193 | rv->blogc = bm_exec_find_binary(argv0, "blogc", "BLOGC"); |
194 | rv->blogc_runserver = bm_exec_find_binary(argv0, "blogc-runserver", |
195 | "BLOGC_RUNSERVER"); |
196 | rv->dev = false0; |
197 | rv->verbose = false0; |
198 | } |
199 | else { |
200 | bm_ctx_free_internal(base); |
201 | rv = base; |
202 | } |
203 | rv->settings = settings; |
204 | |
205 | char *real_filename = realpath(settings_file, NULL((void*)0)); |
206 | rv->settings_fctx = bm_filectx_new(rv, real_filename, NULL((void*)0), NULL((void*)0)); |
207 | rv->root_dir = realpath(dirname(real_filename), NULL((void*)0)); |
208 | free(real_filename); |
209 | |
210 | const char *output_dir = getenv("OUTPUT_DIR"); |
211 | rv->short_output_dir = bc_strdup(output_dir != NULL((void*)0) ? output_dir : "_build"); |
212 | |
213 | if (rv->short_output_dir[0] == '/') { |
214 | rv->output_dir = bc_strdup(rv->short_output_dir); |
215 | } |
216 | else { |
217 | rv->output_dir = bc_strdup_printf("%s/%s", rv->root_dir, |
218 | rv->short_output_dir); |
219 | } |
220 | |
221 | // can't return null and set error after this! |
222 | |
223 | const char *template_dir = bc_trie_lookup(settings->settings, |
224 | "template_dir"); |
225 | |
226 | char *main_template = bc_strdup_printf("%s/%s", template_dir, |
227 | bc_trie_lookup(settings->settings, "main_template")); |
228 | rv->main_template_fctx = bm_filectx_new(rv, main_template, NULL((void*)0), NULL((void*)0)); |
229 | free(main_template); |
230 | |
231 | rv->atom_template_fctx = bm_filectx_new(rv, atom_template, NULL((void*)0), NULL((void*)0)); |
232 | free(atom_template); |
233 | |
234 | const char *content_dir = bc_trie_lookup(settings->settings, "content_dir"); |
235 | const char *post_prefix = bc_trie_lookup(settings->settings, "post_prefix"); |
236 | const char *source_ext = bc_trie_lookup(settings->settings, "source_ext"); |
237 | |
238 | rv->posts_fctx = NULL((void*)0); |
239 | if (settings->posts != NULL((void*)0)) { |
240 | for (size_t i = 0; settings->posts[i] != NULL((void*)0); i++) { |
241 | char *f = bc_strdup_printf("%s/%s/%s%s", content_dir, post_prefix, |
242 | settings->posts[i], source_ext); |
243 | rv->posts_fctx = bc_slist_append(rv->posts_fctx, |
244 | bm_filectx_new(rv, f, settings->posts[i], NULL((void*)0))); |
245 | free(f); |
246 | } |
247 | } |
248 | |
249 | rv->pages_fctx = NULL((void*)0); |
250 | if (settings->pages != NULL((void*)0)) { |
251 | for (size_t i = 0; settings->pages[i] != NULL((void*)0); i++) { |
252 | char *f = bc_strdup_printf("%s/%s%s", content_dir, |
253 | settings->pages[i], source_ext); |
254 | rv->pages_fctx = bc_slist_append(rv->pages_fctx, |
255 | bm_filectx_new(rv, f, settings->pages[i], NULL((void*)0))); |
256 | free(f); |
257 | } |
258 | } |
259 | |
260 | rv->copy_fctx = NULL((void*)0); |
261 | if (settings->copy != NULL((void*)0)) { |
262 | for (size_t i = 0; settings->copy[i] != NULL((void*)0); i++) { |
263 | rv->copy_fctx = bm_filectx_new_r(rv->copy_fctx, rv, |
264 | settings->copy[i]); |
265 | } |
266 | } |
267 | |
268 | return rv; |
269 | } |
270 | |
271 | |
272 | bool_Bool |
273 | bm_ctx_reload(bm_ctx_t *ctx) |
274 | { |
275 | if (ctx == NULL((void*)0) || ctx->settings_fctx == NULL((void*)0)) |
276 | return false0; |
277 | |
278 | if (bm_filectx_changed(ctx->settings_fctx, NULL((void*)0), NULL((void*)0))) { |
279 | // reload everything! we could just reload settings_fctx, as this |
280 | // would force rebuilding everything, but we need to know new/deleted |
281 | // files |
282 | |
283 | // needs to dup path, because it may be freed when reloading. |
284 | char *tmp = bc_strdup(ctx->settings_fctx->path); |
285 | bc_error_t *err = NULL((void*)0); |
286 | ctx = bm_ctx_new(ctx, tmp, NULL((void*)0), &err); |
Value stored to 'ctx' is never read | |
287 | free(tmp); |
288 | if (err != NULL((void*)0)) { |
289 | bc_error_print(err, "blogc-make"); |
290 | bc_error_free(err); |
291 | return false0; |
292 | } |
293 | return true1; |
294 | } |
295 | |
296 | bm_filectx_reload(ctx->main_template_fctx); |
297 | bm_filectx_reload(ctx->atom_template_fctx); |
298 | |
299 | for (bc_slist_t *tmp = ctx->posts_fctx; tmp != NULL((void*)0); tmp = tmp->next) |
300 | bm_filectx_reload((bm_filectx_t*) tmp->data); |
301 | |
302 | for (bc_slist_t *tmp = ctx->pages_fctx; tmp != NULL((void*)0); tmp = tmp->next) |
303 | bm_filectx_reload((bm_filectx_t*) tmp->data); |
304 | |
305 | for (bc_slist_t *tmp = ctx->copy_fctx; tmp != NULL((void*)0); tmp = tmp->next) |
306 | bm_filectx_reload((bm_filectx_t*) tmp->data); |
307 | |
308 | return true1; |
309 | } |
310 | |
311 | |
312 | void |
313 | bm_ctx_free_internal(bm_ctx_t *ctx) |
314 | { |
315 | if (ctx == NULL((void*)0)) |
316 | return; |
317 | |
318 | bm_settings_free(ctx->settings); |
319 | ctx->settings = NULL((void*)0); |
320 | |
321 | free(ctx->root_dir); |
322 | ctx->root_dir = NULL((void*)0); |
323 | free(ctx->short_output_dir); |
324 | ctx->short_output_dir = NULL((void*)0); |
325 | free(ctx->output_dir); |
326 | ctx->output_dir = NULL((void*)0); |
327 | |
328 | bm_atom_destroy(ctx->atom_template_fctx->path); |
329 | |
330 | bm_filectx_free(ctx->main_template_fctx); |
331 | ctx->main_template_fctx = NULL((void*)0); |
332 | bm_filectx_free(ctx->atom_template_fctx); |
333 | ctx->atom_template_fctx = NULL((void*)0); |
334 | bm_filectx_free(ctx->settings_fctx); |
335 | ctx->settings_fctx = NULL((void*)0); |
336 | |
337 | bc_slist_free_full(ctx->posts_fctx, (bc_free_func_t) bm_filectx_free); |
338 | ctx->posts_fctx = NULL((void*)0); |
339 | bc_slist_free_full(ctx->pages_fctx, (bc_free_func_t) bm_filectx_free); |
340 | ctx->pages_fctx = NULL((void*)0); |
341 | bc_slist_free_full(ctx->copy_fctx, (bc_free_func_t) bm_filectx_free); |
342 | ctx->copy_fctx = NULL((void*)0); |
343 | } |
344 | |
345 | |
346 | void |
347 | bm_ctx_free(bm_ctx_t *ctx) |
348 | { |
349 | if (ctx == NULL((void*)0)) |
350 | return; |
351 | bm_ctx_free_internal(ctx); |
352 | free(ctx->blogc); |
353 | free(ctx->blogc_runserver); |
354 | free(ctx); |
355 | } |