add optimized catfile: %{somevar} - saait - the most boring static page generat… | |
git clone git://git.codemadness.org/saait | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 02992aebcd4d0498ec6c49309c4499e2e420f21b | |
parent 97a7e89e3e3204a474abe40c86645672c5edaccf | |
Author: Hiltjo Posthuma <[email protected]> | |
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: | |
M saait.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\… | |
+ 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(errn… | |
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 *… | |
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… | |
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: '%… | |
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 +… | |
- 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], '.'))) |