diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile.am | 21 | ||||
-rw-r--r-- | src/blogc-make/rules.c | 43 | ||||
-rw-r--r-- | src/blogc-make/utils.c | 61 | ||||
-rw-r--r-- | src/blogc-make/utils.h | 15 | ||||
-rw-r--r-- | tests/blogc-make/check_utils.c | 119 |
6 files changed, 236 insertions, 24 deletions
@@ -72,6 +72,7 @@ blogc*.html /tests/blogc-make/check_exec /tests/blogc-make/check_rules /tests/blogc-make/check_settings +/tests/blogc-make/check_utils /tests/blogc-runserver/check_httpd_utils /tests/blogc-runserver/check_mime /tests/common/check_config_parser diff --git a/Makefile.am b/Makefile.am index 7e25694..f33798d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -60,6 +60,7 @@ noinst_HEADERS = \ src/blogc-make/reloader.h \ src/blogc-make/rules.h \ src/blogc-make/settings.h \ + src/blogc-make/utils.h \ src/blogc-runserver/httpd.h \ src/blogc-runserver/httpd-utils.h \ src/blogc-runserver/mime.h \ @@ -240,6 +241,7 @@ libblogc_make_la_SOURCES = \ src/blogc-make/reloader.c \ src/blogc-make/rules.c \ src/blogc-make/settings.c \ + src/blogc-make/utils.c \ $(NULL) libblogc_make_la_CFLAGS = \ @@ -792,6 +794,7 @@ check_PROGRAMS += \ tests/blogc-make/check_atom \ tests/blogc-make/check_rules \ tests/blogc-make/check_settings \ + tests/blogc-make/check_utils \ $(NULL) if USE_LD_WRAP @@ -872,6 +875,24 @@ tests_blogc_make_check_settings_LDADD = \ libblogc_make.la \ libblogc_common.la \ $(NULL) + +tests_blogc_make_check_utils_SOURCES = \ + tests/blogc-make/check_utils.c \ + $(NULL) + +tests_blogc_make_check_utils_CFLAGS = \ + $(CMOCKA_CFLAGS) \ + $(NULL) + +tests_blogc_make_check_utils_LDFLAGS = \ + -no-install \ + $(NULL) + +tests_blogc_make_check_utils_LDADD = \ + $(CMOCKA_LIBS) \ + libblogc_make.la \ + libblogc_common.la \ + $(NULL) endif endif diff --git a/src/blogc-make/rules.c b/src/blogc-make/rules.c index 2f4b119..a491283 100644 --- a/src/blogc-make/rules.c +++ b/src/blogc-make/rules.c @@ -19,6 +19,7 @@ #include "httpd.h" #include "reloader.h" #include "settings.h" +#include "utils.h" #include "rules.h" @@ -82,9 +83,8 @@ index_outputlist(bm_ctx_t *ctx) "html_ext"); const char *index_prefix = bc_trie_lookup(ctx->settings->settings, "index_prefix"); - const char *slash = index_prefix[0] == '\0' && html_ext[0] == '/' ? "" : "/"; - char *f = bc_strdup_printf("%s%s%s%s", ctx->short_output_dir, slash, - index_prefix, html_ext); + char *f = bm_generate_filename(ctx->short_output_dir, index_prefix, NULL, + html_ext); rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL)); free(f); return rv; @@ -140,10 +140,9 @@ atom_outputlist(bm_ctx_t *ctx) bc_slist_t *rv = NULL; const char *atom_prefix = bc_trie_lookup(ctx->settings->settings, "atom_prefix"); - const char *slash = atom_prefix[0] == '\0' ? "" : "/"; const char *atom_ext = bc_trie_lookup(ctx->settings->settings, "atom_ext"); - char *f = bc_strdup_printf("%s%s%s%s", ctx->short_output_dir, slash, - atom_prefix, atom_ext); + char *f = bm_generate_filename(ctx->short_output_dir, atom_prefix, NULL, + atom_ext); rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL)); free(f); return rv; @@ -199,10 +198,9 @@ atom_tags_outputlist(bm_ctx_t *ctx) const char *atom_prefix = bc_trie_lookup(ctx->settings->settings, "atom_prefix"); const char *atom_ext = bc_trie_lookup(ctx->settings->settings, "atom_ext"); - const char *slash = atom_prefix[0] == '\0' ? "" : "/"; for (size_t i = 0; ctx->settings->tags[i] != NULL; i++) { - char *f = bc_strdup_printf("%s%s%s/%s%s", ctx->short_output_dir, slash, - atom_prefix, ctx->settings->tags[i], atom_ext); + char *f = bm_generate_filename(ctx->short_output_dir, atom_prefix, + ctx->settings->tags[i], atom_ext); rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL)); free(f); } @@ -272,13 +270,14 @@ pagination_outputlist(bm_ctx_t *ctx) "pagination_prefix"); const char *html_ext = bc_trie_lookup(ctx->settings->settings, "html_ext"); - const char *slash = pagination_prefix[0] == '\0' ? "" : "/"; bc_slist_t *rv = NULL; for (size_t i = 0; i < pages; i++) { - char *f = bc_strdup_printf("%s%s%s/%d%s", ctx->short_output_dir, slash, - pagination_prefix, i + 1, html_ext); + char *j = bc_strdup_printf("%d", i + 1); + char *f = bm_generate_filename(ctx->short_output_dir, pagination_prefix, + j, html_ext); rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL)); + free(j); free(f); } return rv; @@ -337,12 +336,11 @@ posts_outputlist(bm_ctx_t *ctx) "post_prefix"); const char *html_ext = bc_trie_lookup(ctx->settings->settings, "html_ext"); - const char *slash = post_prefix[0] == '\0' ? "" : "/"; bc_slist_t *rv = NULL; for (size_t i = 0; ctx->settings->posts[i] != NULL; i++) { - char *f = bc_strdup_printf("%s%s%s/%s%s", ctx->short_output_dir, slash, - post_prefix, ctx->settings->posts[i], html_ext); + char *f = bm_generate_filename(ctx->short_output_dir, post_prefix, + ctx->settings->posts[i], html_ext); rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL)); free(f); } @@ -404,14 +402,14 @@ tags_outputlist(bm_ctx_t *ctx) if (!posts_pagination_enabled(ctx, "posts_per_page")) return NULL; - bc_slist_t *rv = NULL; const char *tag_prefix = bc_trie_lookup(ctx->settings->settings, "tag_prefix"); const char *html_ext = bc_trie_lookup(ctx->settings->settings, "html_ext"); - const char *slash = tag_prefix[0] == '\0' ? "" : "/"; + + bc_slist_t *rv = NULL; for (size_t i = 0; ctx->settings->tags[i] != NULL; i++) { - char *f = bc_strdup_printf("%s%s%s/%s%s", ctx->short_output_dir, slash, - tag_prefix, ctx->settings->tags[i], html_ext); + char *f = bm_generate_filename(ctx->short_output_dir, tag_prefix, + ctx->settings->tags[i], html_ext); rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL)); free(f); } @@ -471,11 +469,8 @@ pages_outputlist(bm_ctx_t *ctx) bc_slist_t *rv = NULL; for (size_t i = 0; ctx->settings->pages[i] != NULL; i++) { - bool is_index = (0 == strcmp(ctx->settings->pages[i], "index")) - && (html_ext[0] == '/'); - char *f = bc_strdup_printf("%s%s%s%s", ctx->short_output_dir, - is_index ? "" : "/", is_index ? "" : ctx->settings->pages[i], - html_ext); + char *f = bm_generate_filename(ctx->short_output_dir, NULL, + ctx->settings->pages[i], html_ext); rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL)); free(f); } diff --git a/src/blogc-make/utils.c b/src/blogc-make/utils.c new file mode 100644 index 0000000..b1ff7e1 --- /dev/null +++ b/src/blogc-make/utils.c @@ -0,0 +1,61 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2017 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#include <stdbool.h> +#include <string.h> +#include "../common/utils.h" + + +char* +bm_generate_filename(const char *dir, const char *prefix, const char *fname, + const char *ext) +{ + bool have_prefix = prefix != NULL && prefix[0] != '\0'; + bool have_fname = fname != NULL && fname[0] != '\0'; + bool have_ext = ext != NULL && ext[0] != '\0'; + bool have_ext_noslash = have_ext && ext[0] != '/'; + bool is_index = have_fname && have_ext && ( + (0 == strcmp(fname, "index")) && ext[0] == '/'); + + bc_string_t *rv = bc_string_new(); + + if (dir != NULL && (have_prefix || have_fname || have_ext)) + bc_string_append(rv, dir); + + if ((have_prefix || have_fname || have_ext_noslash) && !is_index) + bc_string_append_c(rv, '/'); + + if (have_prefix) + bc_string_append(rv, prefix); + + // with fname we have posts, pages and tags + if (have_fname) { + if (have_prefix && have_fname && fname[0] != '/') + bc_string_append_c(rv, '/'); + if (!is_index) + bc_string_append(rv, fname); + } + + // no fname means index + else if (have_ext_noslash) { + if (have_fname) + bc_string_append_c(rv, '/'); + if (!have_prefix) + bc_string_append(rv, "index"); + } + + if (have_ext) + bc_string_append(rv, ext); + + if (rv->len == 0) { + bc_string_free(rv, true); + return NULL; + } + + return bc_string_free(rv, false); +} diff --git a/src/blogc-make/utils.h b/src/blogc-make/utils.h new file mode 100644 index 0000000..c15e390 --- /dev/null +++ b/src/blogc-make/utils.h @@ -0,0 +1,15 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2017 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifndef _MAKE_UTILS_H +#define _MAKE_UTILS_H + +char* bm_generate_filename(const char *dir, const char *prefix, const char *fname, + const char *ext); + +#endif /* _MAKE_UTILS_H */ diff --git a/tests/blogc-make/check_utils.c b/tests/blogc-make/check_utils.c new file mode 100644 index 0000000..7858ec4 --- /dev/null +++ b/tests/blogc-make/check_utils.c @@ -0,0 +1,119 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2017 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> + +#include <stdlib.h> + +#include "../../src/blogc-make/utils.h" +#include "../../src/common/utils.h" + + +static void +test_generate_filename(void **state) +{ + char *rv; + + assert_null(bm_generate_filename(NULL, NULL, NULL, NULL)); + assert_null(bm_generate_filename(NULL, "", "", "")); + assert_null(bm_generate_filename("_build", NULL, NULL, NULL)); + assert_null(bm_generate_filename("_build", "", "", "")); + + rv = bm_generate_filename(NULL, NULL, NULL, ".html"); + assert_string_equal(rv, "/index.html"); + free(rv); + + rv = bm_generate_filename(NULL, NULL, NULL, "/index.html"); + assert_string_equal(rv, "/index.html"); + free(rv); + + rv = bm_generate_filename(NULL, "lol", NULL, ".html"); + assert_string_equal(rv, "/lol.html"); + free(rv); + + rv = bm_generate_filename(NULL, "lol", NULL, "/index.html"); + assert_string_equal(rv, "/lol/index.html"); + free(rv); + + rv = bm_generate_filename(NULL, NULL, "foo", ".html"); + assert_string_equal(rv, "/foo.html"); + free(rv); + + rv = bm_generate_filename(NULL, NULL, "foo", "/index.html"); + assert_string_equal(rv, "/foo/index.html"); + free(rv); + + rv = bm_generate_filename(NULL, NULL, "index", ".html"); + assert_string_equal(rv, "/index.html"); + free(rv); + + rv = bm_generate_filename(NULL, NULL, "index", "/index.html"); + assert_string_equal(rv, "/index.html"); + free(rv); + + rv = bm_generate_filename(NULL, "bar", "foo", ".html"); + assert_string_equal(rv, "/bar/foo.html"); + free(rv); + + rv = bm_generate_filename(NULL, "bar", "foo", "/index.html"); + assert_string_equal(rv, "/bar/foo/index.html"); + free(rv); + + rv = bm_generate_filename("_build", NULL, NULL, ".html"); + assert_string_equal(rv, "_build/index.html"); + free(rv); + + rv = bm_generate_filename("_build", NULL, NULL, "/index.html"); + assert_string_equal(rv, "_build/index.html"); + free(rv); + + rv = bm_generate_filename("_build", "lol", NULL, ".html"); + assert_string_equal(rv, "_build/lol.html"); + free(rv); + + rv = bm_generate_filename("_build", "lol", NULL, "/index.html"); + assert_string_equal(rv, "_build/lol/index.html"); + free(rv); + + rv = bm_generate_filename("_build", NULL, "foo", ".html"); + assert_string_equal(rv, "_build/foo.html"); + free(rv); + + rv = bm_generate_filename("_build", NULL, "foo", "/index.html"); + assert_string_equal(rv, "_build/foo/index.html"); + free(rv); + + rv = bm_generate_filename("_build", NULL, "index", ".html"); + assert_string_equal(rv, "_build/index.html"); + free(rv); + + rv = bm_generate_filename("_build", NULL, "index", "/index.html"); + assert_string_equal(rv, "_build/index.html"); + free(rv); + + rv = bm_generate_filename("_build", "bar", "foo", ".html"); + assert_string_equal(rv, "_build/bar/foo.html"); + free(rv); + + rv = bm_generate_filename("_build", "bar", "foo", "/index.html"); + assert_string_equal(rv, "_build/bar/foo/index.html"); + free(rv); +} + + +int +main(void) +{ + const UnitTest tests[] = { + unit_test(test_generate_filename), + }; + return run_tests(tests); +} |