Bug Summary

File:ctx.c
Warning:line 237, column 17
Value stored to 'slash' during its initialization is never read

Annotated Source Code

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