* html.c: implementation of html.h.
*/
-#include <assert.h>
-#include <stddef.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <time.h>
-
+#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;
char *href;
size_t hreflen;
const char *format;
- unsigned long long thresholds[MAXCOLOUR-1];
+ unsigned long long thresholds[MAXCOLOUR];
+ char *titletexts[MAXCOLOUR+1];
time_t now;
};
{
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) {
path[pathlen-1] = c2;
}
-static unsigned long long fetch_size(const void *t, char *path,
+static unsigned long long fetch_size(const void *t,
+ unsigned long xi1, unsigned long xi2,
unsigned long long atime)
{
- unsigned long xi1, xi2;
-
- get_indices(t, path, &xi1, &xi2);
-
return index_query(t, xi2, atime) - index_query(t, xi1, atime);
}
static void add_to_colour_bar(struct html *ctx, int colour, int pixels)
{
int r, g, b;
- char buf[80];
if (colour >= 0 && colour < 256) /* red -> yellow fade */
r = 255, g = colour, b = 0;
else /* background grey */
r = g = b = 240;
- if (colour < 0) {
- /* no title text here */
- } else if (colour == 0) {
- strcpy(buf, "< ");
- round_and_format_age(ctx, ctx->thresholds[0], buf+5, 0);
- } else if (colour == MAXCOLOUR) {
- strcpy(buf, "> ");
- round_and_format_age(ctx, ctx->thresholds[MAXCOLOUR-1], buf+5, 0);
- } else {
- unsigned long long midrange =
- (ctx->thresholds[colour] + ctx->thresholds[colour+1]) / 2;
- round_and_format_age(ctx, midrange, buf, 0);
- }
-
if (pixels > 0) {
htprintf(ctx, "<td style=\"width:%dpx; height:1em; "
"background-color:#%02x%02x%02x\"",
pixels, r, g, b);
if (colour >= 0)
- htprintf(ctx, " title=\"%s\"", buf);
+ htprintf(ctx, " title=\"%s\"", ctx->titletexts[colour]);
htprintf(ctx, "></td>\n");
}
}
atime = ULLONG_MAX;
else
atime = ctx->thresholds[i];
- vec->sizes[i] = fetch_size(ctx->t, path, atime);
+ vec->sizes[i] = fetch_size(ctx->t, xi1, xi2, atime);
}
return vec;
htprintf(ctx, "</td>\n</tr>\n");
}
+int strcmptrailingpathsep(const char *a, const char *b)
+{
+ while (*a == *b && *a)
+ a++, b++;
+
+ if ((*a == pathsep && !a[1] && !*b) ||
+ (*b == pathsep && !b[1] && !*a))
+ return 0;
+
+ return (int)(unsigned char)*a - (int)(unsigned char)*b;
+}
+
char *html_query(const void *t, unsigned long index,
const struct html_config *cfg)
{
*/
htprintf(ctx, "<head>\n");
trie_getpath(t, index, path);
- htprintf(ctx, "<title>agedu: ");
+ htprintf(ctx, "<title>%s: ", PNAME);
htescape(ctx, path, strlen(path), 0);
htprintf(ctx, "</title>\n");
htprintf(ctx, "</head>\n");
*zp = '\0';
index2 = trie_before(t, path);
trie_getpath(t, index2, path2);
- if (!strcmp(path, path2) && cfg->format) {
+ if (!strcmptrailingpathsep(path, path2) && cfg->format) {
snprintf(href, hreflen, cfg->format, index2);
if (!*href) /* special case that we understand */
strcpy(href, "./");
ctx->oldest = round_and_format_age(ctx, ctx->oldest, agebuf1, 0);
ctx->newest = round_and_format_age(ctx, ctx->newest, agebuf2, 0);
}
- for (i = 0; i < MAXCOLOUR-1; i++) {
+ for (i = 0; i < MAXCOLOUR; i++) {
ctx->thresholds[i] =
- ctx->oldest + (ctx->newest - ctx->oldest) * i / MAXCOLOUR;
+ ctx->oldest + (ctx->newest - ctx->oldest) * i / (MAXCOLOUR-1);
+ }
+ for (i = 0; i <= MAXCOLOUR; i++) {
+ char buf[80];
+
+ if (i == 0) {
+ strcpy(buf, "< ");
+ round_and_format_age(ctx, ctx->thresholds[0], buf+5, 0);
+ } else if (i == MAXCOLOUR) {
+ strcpy(buf, "> ");
+ round_and_format_age(ctx, ctx->thresholds[MAXCOLOUR-1], buf+5, 0);
+ } else {
+ unsigned long long midrange =
+ (ctx->thresholds[i-1] + ctx->thresholds[i]) / 2;
+ round_and_format_age(ctx, midrange, buf, 0);
+ }
+
+ ctx->titletexts[i] = dupstr(buf);
}
htprintf(ctx, "<p align=center>Key to colour coding (mouse over for more detail):\n");
htprintf(ctx, "<p align=center style=\"padding: 0; margin-top:0.4em; "
* Find the total size of our entire subdirectory. We'll use
* that as the scale for all the colour bars in this report.
*/
- ctx->totalsize = fetch_size(t, path, ULLONG_MAX);
+ get_indices(t, path, &xi1, &xi2);
+ ctx->totalsize = fetch_size(t, xi1, xi2, ULLONG_MAX);
/*
* Generate a report line for the whole subdirectory.