From c071ac260a24561c889643b7f8df37950a597137 Mon Sep 17 00:00:00 2001 From: "Rafael G. Martins" Date: Sun, 30 Apr 2017 17:28:32 +0200 Subject: make: copy rule should support directories, recursively now any directories listed in the [copy] section of blogcfile will have its files copied recursively to the output dir. this is useful for big chunks of generated files, e.g. doxygen documentation. --- src/blogc-make/ctx.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- src/blogc-make/ctx.h | 1 + src/blogc-make/rules.c | 6 ++++-- 3 files changed, 52 insertions(+), 4 deletions(-) (limited to 'src/blogc-make') diff --git a/src/blogc-make/ctx.c b/src/blogc-make/ctx.c index e062474..ee050a4 100644 --- a/src/blogc-make/ctx.c +++ b/src/blogc-make/ctx.c @@ -7,10 +7,13 @@ */ #include +#include +#include #include #include #include #include +#include #include "../common/error.h" #include "../common/file.h" #include "../common/utils.h" @@ -50,6 +53,48 @@ bm_filectx_new(bm_ctx_t *ctx, const char *filename) } +bc_slist_t* +bm_filectx_new_r(bc_slist_t *l, bm_ctx_t *ctx, const char *filename) +{ + if (ctx == NULL || filename == NULL) + return NULL; + + char *f = filename[0] == '/' ? bc_strdup(filename) : + bc_strdup_printf("%s/%s", ctx->root_dir, filename); + + struct stat buf; + if (0 != stat(f, &buf)) { + free(f); + return l; + } + + if (S_ISDIR(buf.st_mode)) { + DIR *dir = opendir(f); + if (dir == NULL) { + free(f); + return l; + } + + struct dirent *e; + while (NULL != (e = readdir(dir))) { + if ((0 == strcmp(e->d_name, ".")) || (0 == strcmp(e->d_name, ".."))) + continue; + char *tmp = bc_strdup_printf("%s/%s", filename, e->d_name); + l = bm_filectx_new_r(l, ctx, tmp); + free(tmp); + } + + closedir(dir); + free(f); + return l; + } + + l = bc_slist_append(l, bm_filectx_new(ctx, filename)); + free(f); + return l; +} + + bool bm_filectx_changed(bm_filectx_t *ctx, time_t *tv_sec, long *tv_nsec) { @@ -208,8 +253,8 @@ bm_ctx_new(bm_ctx_t *base, const char *settings_file, const char *argv0, rv->copy_fctx = NULL; if (settings->copy != NULL) { for (size_t i = 0; settings->copy[i] != NULL; i++) { - rv->copy_fctx = bc_slist_append(rv->copy_fctx, - bm_filectx_new(rv, settings->copy[i])); + rv->copy_fctx = bm_filectx_new_r(rv->copy_fctx, rv, + settings->copy[i]); } } diff --git a/src/blogc-make/ctx.h b/src/blogc-make/ctx.h index 962c029..1c9d8b0 100644 --- a/src/blogc-make/ctx.h +++ b/src/blogc-make/ctx.h @@ -64,6 +64,7 @@ typedef struct { } bm_ctx_t; bm_filectx_t* bm_filectx_new(bm_ctx_t *ctx, const char *filename); +bc_slist_t* bm_filectx_new_r(bc_slist_t *l, bm_ctx_t *ctx, const char *filename); bool bm_filectx_changed(bm_filectx_t *ctx, time_t *tv_sec, long *tv_nsec); void bm_filectx_reload(bm_filectx_t *ctx); void bm_filectx_free(bm_filectx_t *fctx); diff --git a/src/blogc-make/rules.c b/src/blogc-make/rules.c index e9755a2..81fda35 100644 --- a/src/blogc-make/rules.c +++ b/src/blogc-make/rules.c @@ -462,9 +462,11 @@ copy_outputlist(bm_ctx_t *ctx) return NULL; bc_slist_t *rv = NULL; - for (size_t i = 0; ctx->settings->copy[i] != NULL; i++) { + // we iterate over ctx->copy_fctx list instead of ctx->settings->copy, + // because bm_ctx_new() expands directories into its files, recursively. + for (bc_slist_t *s = ctx->copy_fctx; s != NULL; s = s->next) { char *f = bc_strdup_printf("%s/%s", ctx->short_output_dir, - ctx->settings->copy[i]); + ((bm_filectx_t*) s->data)->short_path); rv = bc_slist_append(rv, bm_filectx_new(ctx, f)); free(f); } -- cgit v1.2.3-18-g5258