saait

Simple static page generator
git clone https://git.sinitax.com/codemadness/saait
Log | Files | Refs | README | LICENSE | Upstream | sfeed.txt

commit 02992aebcd4d0498ec6c49309c4499e2e420f21b
parent 97a7e89e3e3204a474abe40c86645672c5edaccf
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Sun, 21 Jan 2018 16:15:30 +0100

add optimized catfile: %{somevar}

this reads and appends the contents of the value in variable 'somevar'

Diffstat:
Msaait.c | 55+++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/saait.c b/saait.c @@ -8,6 +8,7 @@ #include <unistd.h> #endif +#define READ_BUF_SIZ 16384 #define LEN(s) (sizeof(s)/sizeof(*s)) struct variable { @@ -79,6 +80,32 @@ efopen(const char *path, const char *mode) return fp; } +void +catfile(FILE *fpin, const char *ifile, FILE *fpout, const char *ofile) +{ + char buf[READ_BUF_SIZ]; + size_t r, w; + + while (!feof(fpin)) { + if (!(r = fread(buf, 1, sizeof(buf), fpin))) + break; + if ((w = fwrite(buf, 1, r, fpout)) != r) + break; + if (r != sizeof(buf)) + break; + } + if (ferror(fpin)) { + fprintf(stderr, "%s -> %s: error reading data from stream: %s\n", + ifile, ofile, strerror(errno)); + exit(1); + } + if (ferror(fpout)) { + fprintf(stderr, "%s -> %s: error writing data to stream: %s\n", + ifile, ofile, strerror(errno)); + exit(1); + } +} + char * readfile(const char *file) { @@ -89,18 +116,20 @@ readfile(const char *file) fp = efopen(file, "rb"); buf = ecalloc(1, size + 1); /* always allocate an empty buffer */ while (!feof(fp)) { - if (len + BUFSIZ + 1 > size) { + if (len + READ_BUF_SIZ + 1 > size) { /* allocate size: common case is small textfiles */ - size += (BUFSIZ * 10); + size += READ_BUF_SIZ; if (!(buf = realloc(buf, size + 1))) { fprintf(stderr, "realloc: %s\n", strerror(errno)); exit(1); } } - if (!(n = fread(&buf[len], 1, BUFSIZ, fp))) + if (!(n = fread(&buf[len], 1, READ_BUF_SIZ, fp))) break; len += n; buf[len] = '\0'; + if (n != READ_BUF_SIZ) + break; } if (ferror(fp)) { fprintf(stderr, "fread: file: %s: %s\n", file, strerror(errno)); @@ -249,6 +278,7 @@ readconfig(const char *file) void writepage(FILE *fp, const char *filename, struct variable *c, char *s) { + FILE *fpin; struct variable *v; char *key; size_t keylen, line = 0; @@ -257,6 +287,7 @@ writepage(FILE *fp, const char *filename, struct variable *c, char *s) for (; *s; s++) { op = *s; switch (*s) { + case '%': /* insert contents of filename set in variable */ case '#': /* insert value non-escaped */ case '$': /* insert value escaped */ if (*(s + 1) == '{') { @@ -291,12 +322,19 @@ writepage(FILE *fp, const char *filename, struct variable *c, char *s) key[keylen] = tmpc; /* restore NUL terminator to original */ if (!v) { - fprintf(stderr, "%s:%zu: unknown variable: '%.*s'\n", + fprintf(stderr, "%s:%zu: error: undefined variable: '%.*s'\n", filename, line + 1, (int)keylen, key); exit(1); } switch (op) { + case '%': + if (!v->value[0]) + break; + fpin = efopen(v->value, "rb"); + catfile(fpin, v->value, fp, filename); + fclose(fpin); + break; case '$': xmlencode(v->value, fp); break; @@ -320,7 +358,8 @@ main(int argc, char *argv[]) struct block *b; struct variable *c, *v; char file[PATH_MAX + 1], htmlfile[PATH_MAX + 1], outputfile[PATH_MAX + 1], *p; - int i, j, k, r; + size_t i, j, k; + int r; if (pledge("stdio cpath rpath wpath", NULL) == -1) { fprintf(stderr, "pledge: %s\n", strerror(errno)); @@ -350,7 +389,7 @@ main(int argc, char *argv[]) b = &templates[i].blocks[j]; r = snprintf(file, sizeof(file), "%s/%s", templatedir, b->name); - if (r < 0 || (size_t) r >= sizeof(file)) { + if (r < 0 || (size_t)r >= sizeof(file)) { fprintf(stderr, "path truncated: '%s/%s'\n", templatedir, b->name); exit(1); @@ -365,7 +404,7 @@ main(int argc, char *argv[]) continue; r = snprintf(file, sizeof(file), "%s/%s", outputdir, templates[i].name); - if (r < 0 || (size_t) r >= sizeof(file)) { + if (r < 0 || (size_t)r >= sizeof(file)) { fprintf(stderr, "path truncated: '%s/%s'\n", outputdir, templates[i].name); exit(1); @@ -376,7 +415,7 @@ main(int argc, char *argv[]) } /* pages */ - for (i = 0; i < argc; i++) { + for (i = 0; i < (size_t)argc; i++) { c = readconfig(argv[i]); if ((p = strrchr(argv[i], '.')))