ssnail

crappy and opinionated static site generator
git clone https://git.e1e0.net/ssnail.git
Log | Files | Refs | README | LICENSE

commit 5d8bca26b9f4c263a87161a4d5485b0fe4f8a804
parent 1cbec25e63e0a6243547ceda6f6cd880a6926d5a
Author: Paco Esteban <paco@e1e0.net>
Date:   Tue, 16 Jun 2020 17:23:30 +0200

reorganize code a bit

* separate helpers functions
* cleanup a bit variable declarations generally
* reorg includes and function prototypes.

Diffstat:
MMakefile | 4++--
Ahelpers.c | 161+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahelpers.h | 26++++++++++++++++++++++++++
Mssnail.c | 219+++++++++++++++----------------------------------------------------------------
4 files changed, 229 insertions(+), 181 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,9 +1,9 @@ PROG = ssnail -# SRCS += ssnail.c +SRCS += ssnail.c helpers.c LDFLAGS += -L/usr/local/lib LDADD += -llowdown -lm -CFLAGS += -I/usr/local/include +CFLAGS += -I/usr/local/include -I${.CURDIR} .include <bsd.prog.mk> diff --git a/helpers.c b/helpers.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2020 Paco Esteban <paco@e1e0.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include <sys/stat.h> +#include <sys/syslimits.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "helpers.h" + +int +build_full_path(char fullpath[PATH_MAX], char *dir, char *file) +{ + // build the full path + (void)strlcpy(fullpath, dir, PATH_MAX); + if (fullpath[strlen(fullpath)-2] != '/') + (void)strlcat(fullpath, "/", PATH_MAX); + (void)strlcat(fullpath, file, PATH_MAX); + + return 1; +} + +int +copy_file(const char *source_file, const char *dest_file, int force) +{ + FILE *src, *dst; + struct stat st; + char ch; + long long src_mtime, dst_mtime; + + if (stat(source_file, &st) == -1) + return -1; + src_mtime = st.st_mtim.tv_sec; + + if (stat(dest_file, &st) == -1) { // dst file does not have to exist + if (errno != ENOENT) + return -1; + dst_mtime = 0; + } else { + dst_mtime = st.st_mtim.tv_sec; + } + + if ((src_mtime > dst_mtime) || force) { + if ((src = fopen(source_file, "r")) == NULL) + return -1; + if ((dst = fopen(dest_file, "w")) == NULL) + return -1; + + printf("copying %s --> %s\n", source_file, dest_file); + while ((ch = fgetc(src)) != EOF) + fputc(ch, dst); + + fclose(src); + fclose(dst); + } + + return 0; +} + +const char * +get_filename_ext(const char *filename) +{ + const char *dot = strrchr(filename, '.'); + if(!dot || dot == filename) + return ""; + return dot + 1; +} + +int +load_from_file(char **buffer, char *path) +{ + long length; + FILE *f = NULL; + + if ((f = fopen(path, "r")) == NULL) + return 0; + + if (f) { + fseek(f, 0, SEEK_END); // go to the end of file + length = ftell(f); // record the length of the file + fseek(f, 0, SEEK_SET); // go to the start again + *buffer = malloc(length + 1); + if (*buffer) + fread(*buffer, 1, length, f); + fclose(f); + /* add null terminator to string. + * apparently this is not the same as: + * *buffer[length] = '\0'; + * but I do not know why ... + */ + *(*buffer + length) = '\0'; + } + + return length + 1; +} + +char * +str_rep(const char *s, const char *oldW, const char *newW) +{ + char *r; + int i, cnt = 0; + int newWlen = strlen(newW); + int oldWlen = strlen(oldW); + + if (newWlen == 0 || oldWlen == 0) + return NULL; + + // Counting the number of times old word + // occur in the string + for (i = 0; s[i] != '\0'; i++) { + if (strstr(&s[i], oldW) == &s[i]) { + cnt++; + // Jumping to index after the old word. + i += oldWlen - 1; + } + } + + // Making new string long enough + r = (char *)malloc(i + cnt * (newWlen - oldWlen) + 1); + if (!r) return NULL; + + i = 0; + while (*s) { + /* + * compare the substring the old word + * if found (pointers are equal), copy new word in 'i' position + * of result. Then increment by the lenght so we do not check + * unnecessarily. + */ + if (strstr(s, oldW) == s) { + /* + * On the original example it was done like this: + * strcpy(&r[i], newW); + * I think there's no need to dereference and reference + * again. + */ + strcpy(r+i, newW); + i += newWlen; + s += oldWlen; + } else // if not copy the char and increment pointers + r[i++] = *s++; + } + + r[i] = '\0'; + return r; +} diff --git a/helpers.h b/helpers.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020 Paco Esteban <paco@e1e0.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef HELPERS_H +#define HELPERS_H + +int build_full_path(char *, char *, char *); +int copy_file(const char *, const char *, int); +const char *get_filename_ext(const char *); +int load_from_file(char **, char *); +char *str_rep(const char *, const char *, const char *); + +#endif /* HELPERS_H */ diff --git a/ssnail.c b/ssnail.c @@ -14,13 +14,13 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <dirent.h> -#include <err.h> -#include <errno.h> #include <sys/queue.h> #include <sys/stat.h> -#include <sys/types.h> #include <sys/syslimits.h> +#include <sys/types.h> +#include <dirent.h> +#include <err.h> +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -29,6 +29,8 @@ #include <lowdown.h> +#include "helpers.h" + #define MAX_META 255 struct article { @@ -50,30 +52,33 @@ struct article { struct article *a = NULL; SLIST_HEAD(listhead, article) head; -char *str_rep(const char *, const char *, const char *); -int gen_html(struct article *); -int build_full_path(char *, char *, char *); -int load_from_file(char **, char *); -void usage(); -int populate_article_entry(struct article *); -int write_html(struct article *, char *, char *); -void articleq_free(struct listhead *); -int generate_index(struct listhead *, char *, char *, char *); -int process_dir(char[PATH_MAX], char[PATH_MAX], int); -const char *get_filename_ext(const char *); -int copy_file(const char *, const char *, int); +void articleq_free(struct listhead *); +int gen_html(struct article *); +int generate_index(struct listhead *, char *, char *, char *); +int populate_article_entry(struct article *); +int process_dir(char[PATH_MAX], char[PATH_MAX], int); +void usage(); +int write_html(struct article *, char *, char *); + +void +usage() +{ + // TODO + printf("usage\n"); + exit(1); +} int main(int argc, char *argv[]) { - DIR *dirp; - struct dirent *dp; - int ch, force = 0, index = 0, needs_index = 0; - char srcdir[PATH_MAX] = "", dstdir[PATH_MAX] = "", - header_tpl[PATH_MAX] = "./_header.html", - footer_tpl[PATH_MAX] = "./_footer.html", - *fbuf = NULL; - struct article *ap = NULL; + DIR *dirp; + struct dirent *dp; + int ch, force = 0, index = 0, needs_index = 0; + char srcdir[PATH_MAX] = "", dstdir[PATH_MAX] = "", + header_tpl[PATH_MAX] = "./_header.html", + footer_tpl[PATH_MAX] = "./_footer.html", + *fbuf = NULL; + struct article *ap = NULL; while ((ch = getopt(argc, argv, "F:H:d:fis:")) != -1) { switch (ch) { @@ -134,7 +139,7 @@ int generate_index(struct listhead *h, char head_tpl[PATH_MAX], char foot_tpl[PATH_MAX], char *dst_dir) { - struct article *a; + struct article *a; char *header = NULL, *footer = NULL; FILE *fout; int r = -1; @@ -194,65 +199,14 @@ articleq_free(struct listhead *h) } } -char * -str_rep(const char *s, const char *oldW, const char *newW) -{ - char *r; - int i, cnt = 0; - int newWlen = strlen(newW); - int oldWlen = strlen(oldW); - - if (newWlen == 0 || oldWlen == 0) - return NULL; - - // Counting the number of times old word - // occur in the string - for (i = 0; s[i] != '\0'; i++) { - if (strstr(&s[i], oldW) == &s[i]) { - cnt++; - // Jumping to index after the old word. - i += oldWlen - 1; - } - } - - // Making new string long enough - r = (char *)malloc(i + cnt * (newWlen - oldWlen) + 1); - if (!r) return NULL; - - i = 0; - while (*s) { - /* - * compare the substring the old word - * if found (pointers are equal), copy new word in 'i' position - * of result. Then increment by the lenght so we do not check - * unnecessarily. - */ - if (strstr(s, oldW) == s) { - /* - * On the original example it was done like this: - * strcpy(&r[i], newW); - * I think there's no need to dereference and reference - * again. - */ - strcpy(r+i, newW); - i += newWlen; - s += oldWlen; - } else // if not copy the char and increment pointers - r[i++] = *s++; - } - - r[i] = '\0'; - return r; -} - int gen_html(struct article *a) { - struct lowdown_opts opts; - struct lowdown_metaq mq; - struct lowdown_meta *md; - int r = 0; - size_t orig_size = 0; + struct lowdown_opts opts; + struct lowdown_metaq mq; + struct lowdown_meta *md; + int r = 0; + size_t orig_size = 0; TAILQ_INIT(&mq); // create the queue(linked list) of lowdown_meta memset(&opts, 0, sizeof(struct lowdown_opts)); // init opts to 0 @@ -343,7 +297,7 @@ out: int populate_article_entry(struct article *ap) { - struct stat st; + struct stat st; int retval = -1; int len = 0; @@ -369,60 +323,12 @@ out: } int -build_full_path(char fullpath[PATH_MAX], char *dir, char *file) -{ - // build the full path - (void)strlcpy(fullpath, dir, PATH_MAX); - if (fullpath[strlen(fullpath)-2] != '/') - (void)strlcat(fullpath, "/", PATH_MAX); - (void)strlcat(fullpath, file, PATH_MAX); - - return 1; -} - -int -load_from_file(char **buffer, char *path) -{ - long length; - FILE *f = NULL; - - if ((f = fopen(path, "r")) == NULL) - return 0; - - if (f) { - fseek(f, 0, SEEK_END); // go to the end of file - length = ftell(f); // record the length of the file - fseek(f, 0, SEEK_SET); // go to the start again - *buffer = malloc(length + 1); - if (*buffer) - fread(*buffer, 1, length, f); - fclose(f); - /* add null terminator to string. - * apparently this is not the same as: - * *buffer[length] = '\0'; - * but I do not know why ... - */ - *(*buffer + length) = '\0'; - } - - return length + 1; -} - -void -usage() -{ - // TODO - printf("usage\n"); - exit(1); -} - -int process_dir(char orig[PATH_MAX], char dest[PATH_MAX], int force) { - DIR *dirp; - struct dirent *dp; - struct stat st; - int retval = -1; + DIR *dirp; + struct dirent *dp; + struct stat st; + int retval = -1; if (stat(dest, &st) == -1 && errno == ENOENT) { if (mkdir(dest, 0755) == -1) @@ -474,48 +380,3 @@ out: closedir(dirp); return retval; } - -const char * -get_filename_ext(const char *filename) { - const char *dot = strrchr(filename, '.'); - if(!dot || dot == filename) - return ""; - return dot + 1; -} - -int -copy_file(const char *source_file, const char *dest_file, int force) -{ - FILE *src, *dst; - struct stat st; - char ch; - long long src_mtime, dst_mtime; - - if (stat(source_file, &st) == -1) - return -1; - src_mtime = st.st_mtim.tv_sec; - - if (stat(dest_file, &st) == -1) { // dst file does not have to exist - if (errno != ENOENT) - return -1; - dst_mtime = 0; - } else { - dst_mtime = st.st_mtim.tv_sec; - } - - if ((src_mtime > dst_mtime) || force) { - if ((src = fopen(source_file, "r")) == NULL) - return -1; - if ((dst = fopen(dest_file, "w")) == NULL) - return -1; - - printf("copying %s --> %s\n", source_file, dest_file); - while ((ch = fgetc(src)) != EOF) - fputc(ch, dst); - - fclose(src); - fclose(dst); - } - - return 0; -}