X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/agedu/blobdiff_plain/373a02e53778079f10f67bd33a948c4f6f2be6da..cc7db507cc53258e23c148c690c9e450214f93ac:/html.c diff --git a/html.c b/html.c index 1daabe6..db6c25b 100644 --- a/html.c +++ b/html.c @@ -2,26 +2,14 @@ * html.c: implementation of html.h. */ -#include -#include -#include -#include -#include -#include -#include -#include - +#include "agedu.h" #include "html.h" -#include "malloc.h" +#include "alloc.h" #include "trie.h" #include "index.h" -#define lenof(x) ( sizeof((x)) / sizeof(*(x)) ) - #define MAXCOLOUR 511 -extern char pathsep; - struct html { char *buf; size_t buflen, bufsize; @@ -39,9 +27,16 @@ static void vhtprintf(struct html *ctx, char *fmt, va_list ap) { va_list ap2; int size, size2; + char testbuf[2]; va_copy(ap2, ap); - size = vsnprintf(NULL, 0, fmt, ap2); + /* + * Some C libraries (Solaris, I'm looking at you) don't like + * an output buffer size of zero in vsnprintf, but will return + * sensible values given any non-zero buffer size. Hence, we + * use testbuf to gauge the length of the string. + */ + size = vsnprintf(testbuf, 1, fmt, ap2); va_end(ap2); if (ctx->buflen + size >= ctx->bufsize) { @@ -166,12 +161,14 @@ static void get_indices(const void *t, char *path, unsigned long *xi1, unsigned long *xi2) { size_t pathlen = strlen(path); + int c1 = path[pathlen], c2 = (pathlen > 0 ? path[pathlen-1] : 0); *xi1 = trie_before(t, path); - path[pathlen] = '\001'; - path[pathlen+1] = '\0'; + make_successor(path); *xi2 = trie_before(t, path); - path[pathlen] = '\0'; + path[pathlen] = c1; + if (pathlen > 0) + path[pathlen-1] = c2; } static unsigned long long fetch_size(const void *t, char *path, @@ -344,7 +341,7 @@ static void write_report_line(struct html *ctx, struct vector *vec) size = vec->sizes[MAXCOLOUR]; htprintf(ctx, "\n" "%lluMb\n", - ((size + ((1<<11)-1)) >> 11)); /* convert to Mb, rounding up */ + ((size + ((1<<20)-1)) >> 20)); /* convert to Mb, rounding up */ /* * Generate a colour bar. @@ -393,7 +390,7 @@ char *html_query(const void *t, unsigned long index, struct html actx, *ctx = &actx; char *path, *path2, *p, *q, *href; char agebuf1[80], agebuf2[80]; - size_t pathlen, hreflen; + size_t pathlen, subdirpos, hreflen; unsigned long index2; int i; struct vector **vecs; @@ -426,7 +423,7 @@ char *html_query(const void *t, unsigned long index, */ htprintf(ctx, "\n"); trie_getpath(t, index, path); - htprintf(ctx, "agedu: "); + htprintf(ctx, "<title>%s: ", PNAME); htescape(ctx, path, strlen(path), 0); htprintf(ctx, "\n"); htprintf(ctx, "\n"); @@ -444,26 +441,37 @@ char *html_query(const void *t, unsigned long index, */ htprintf(ctx, "

\n"); q = path; - for (p = strchr(path, pathsep); p; p = strchr(p+1, pathsep)) { + for (p = strchr(path, pathsep); p && p[1]; p = strchr(p, pathsep)) { int doing_href = 0; + char c, *zp; + /* * See if this path prefix exists in the trie. If so, * generate a hyperlink. */ - *p = '\0'; + zp = p; + if (p == path) /* special case for "/" at start */ + zp++; + + p++; + + c = *zp; + *zp = '\0'; index2 = trie_before(t, path); trie_getpath(t, index2, path2); if (!strcmp(path, path2) && cfg->format) { snprintf(href, hreflen, cfg->format, index2); + if (!*href) /* special case that we understand */ + strcpy(href, "./"); htprintf(ctx, "", href); doing_href = 1; } - *p = pathsep; - htescape(ctx, q, p - q, 1); - q = p + 1; + *zp = c; + htescape(ctx, q, zp - q, 1); if (doing_href) htprintf(ctx, ""); - htescape(ctx, q, p - q, 1); + htescape(ctx, zp, p - zp, 1); + q = p; } htescape(ctx, q, strlen(q), 1); htprintf(ctx, "\n"); @@ -529,6 +537,9 @@ char *html_query(const void *t, unsigned long index, get_indices(t, path, &xi1, &xi2); xi1++; pathlen = strlen(path); + subdirpos = pathlen + 1; + if (pathlen > 0 && path[pathlen-1] == pathsep) + subdirpos--; while (xi1 < xi2) { trie_getpath(t, xi1, path2); get_indices(t, ctx->path2, &xj1, &xj2); @@ -540,7 +551,7 @@ char *html_query(const void *t, unsigned long index, vecs = sresize(vecs, vecsize, struct vector *); } assert(strlen(path2) > pathlen); - vecs[nvecs] = make_vector(ctx, path2, 1, path2 + pathlen + 1); + vecs[nvecs] = make_vector(ctx, path2, 1, path2 + subdirpos); for (i = 0; i <= MAXCOLOUR; i++) vecs[0]->sizes[i] -= vecs[nvecs]->sizes[i]; nvecs++;