Come clean about a false-positive scenario in agedu. I don't have
[sgt/agedu] / html.c
diff --git a/html.c b/html.c
index d6d6ad1..dacd68c 100644 (file)
--- a/html.c
+++ b/html.c
@@ -24,7 +24,7 @@ struct html {
     time_t now;
 };
 
-static void vhtprintf(struct html *ctx, char *fmt, va_list ap)
+static void vhtprintf(struct html *ctx, const char *fmt, va_list ap)
 {
     va_list ap2;
     int size, size2;
@@ -50,7 +50,7 @@ static void vhtprintf(struct html *ctx, char *fmt, va_list ap)
     ctx->buflen += size;
 }
 
-static void htprintf(struct html *ctx, char *fmt, ...)
+static void htprintf(struct html *ctx, const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
@@ -176,7 +176,21 @@ static unsigned long long fetch_size(const void *t,
                                     unsigned long xi1, unsigned long xi2,
                                     unsigned long long atime)
 {
-    return index_query(t, xi2, atime) - index_query(t, xi1, atime);
+    if (xi2 - xi1 == 1) {
+       /*
+        * We are querying an individual file, so we should not
+        * depend on the index entries either side of the node,
+        * since they almost certainly don't both exist. Instead,
+        * just look up the file's size and atime in the main trie.
+        */
+       const struct trie_file *f = trie_getfile(t, xi1);
+       if (f->atime < atime)
+           return f->size;
+       else
+           return 0;
+    } else {
+       return index_query(t, xi2, atime) - index_query(t, xi1, atime);
+    }
 }
 
 static void htescape(struct html *ctx, const char *s, int n, int italics)
@@ -235,8 +249,9 @@ static void end_colour_bar(struct html *ctx)
 }
 
 struct vector {
-    int want_href;
+    int want_href, essential;
     char *name;
+    int literal; /* should the name be formatted in fixed-pitch? */
     unsigned long index;
     unsigned long long sizes[MAXCOLOUR+1];
 };
@@ -260,18 +275,25 @@ int vec_compare(const void *av, const void *bv)
        return -1;
     else if (a->index > b->index)
        return +1;
+    else if (a->essential < b->essential)
+       return +1;
+    else if (a->essential > b->essential)
+       return -1;
     return 0;
 }
 
 static struct vector *make_vector(struct html *ctx, char *path,
-                                 int want_href, char *name)
+                                 int want_href, int essential,
+                                 char *name, int literal)
 {
     unsigned long xi1, xi2;
     struct vector *vec = snew(struct vector);
     int i;
 
     vec->want_href = want_href;
+    vec->essential = essential;
     vec->name = name ? dupstr(name) : NULL;
+    vec->literal = literal;
 
     get_indices(ctx->t, path, &xi1, &xi2);
 
@@ -295,12 +317,31 @@ static void print_heading(struct html *ctx, const char *title)
             "<td colspan=4 align=center>%s</td>\n</tr>\n", title);
 }
 
+static void compute_display_size(unsigned long long size,
+                                const char **fmt, double *display_size)
+{
+    static const char *const fmts[] = {
+       "%g b", "%g Kb", "%#.1f Mb", "%#.1f Gb", "%#.1f Tb",
+       "%#.1f Pb", "%#.1f Eb", "%#.1f Zb", "%#.1f Yb"
+    };
+    int shift = 0;
+
+    while (size >= 1024 && shift < lenof(fmts)-1) {
+       size >>= 10;
+       shift++;
+    }
+    *display_size = (double)size;
+    *fmt = fmts[shift];
+}
+
 #define PIXEL_SIZE 600                /* FIXME: configurability? */
 static void write_report_line(struct html *ctx, struct vector *vec)
 {
     unsigned long long size, asize, divisor;
+    double display_size;
     int pix, newpix;
     int i;
+    const char *unitsfmt;
 
     /*
      * A line with literally zero space usage should not be
@@ -311,7 +352,7 @@ static void write_report_line(struct html *ctx, struct vector *vec)
      * case we must fiddle about to prevent divisions by zero in
      * the code below.
      */
-    if (!vec->sizes[MAXCOLOUR] && vec->want_href)
+    if (!vec->sizes[MAXCOLOUR] && !vec->essential)
        return;
     divisor = ctx->totalsize;
     if (!divisor) {
@@ -322,9 +363,11 @@ static void write_report_line(struct html *ctx, struct vector *vec)
      * Find the total size of this subdirectory.
      */
     size = vec->sizes[MAXCOLOUR];
+    compute_display_size(size, &unitsfmt, &display_size);
     htprintf(ctx, "<tr>\n"
-            "<td style=\"padding: 0.2em; text-align: right\">%lluMb</td>\n",
-            ((size + ((1<<20)-1)) >> 20)); /* convert to Mb, rounding up */
+              "<td style=\"padding: 0.2em; text-align: right\">");
+    htprintf(ctx, unitsfmt, display_size);
+    htprintf(ctx, "</td>\n");
 
     /*
      * Generate a colour bar.
@@ -360,7 +403,11 @@ static void write_report_line(struct html *ctx, struct vector *vec)
            htprintf(ctx, "<a href=\"%s\">", ctx->href);
            doing_href = 1;
        }
+       if (vec->literal)
+           htprintf(ctx, "<code>");
        htescape(ctx, vec->name, strlen(vec->name), 1);
+       if (vec->literal)
+           htprintf(ctx, "</code>");
        if (doing_href)
            htprintf(ctx, "</a>");
     }
@@ -536,7 +583,7 @@ char *html_query(const void *t, unsigned long index,
     vecsize = 64;
     vecs = snewn(vecsize, struct vector *);
     nvecs = 1;
-    vecs[0] = make_vector(ctx, path, 0, NULL);
+    vecs[0] = make_vector(ctx, path, 0, 1, NULL, 0);
     print_heading(ctx, "Overall");
     write_report_line(ctx, vecs[0]);
 
@@ -557,14 +604,15 @@ char *html_query(const void *t, unsigned long index,
        trie_getpath(t, xi1, path2);
        get_indices(t, ctx->path2, &xj1, &xj2);
        xi1 = xj2;
-       if (xj2 - xj1 <= 1)
+       if (!cfg->showfiles && xj2 - xj1 <= 1)
            continue;                  /* skip individual files */
        if (nvecs >= vecsize) {
            vecsize = nvecs * 3 / 2 + 64;
            vecs = sresize(vecs, vecsize, struct vector *);
        }
        assert(strlen(path2) > pathlen);
-       vecs[nvecs] = make_vector(ctx, path2, 1, path2 + subdirpos);
+       vecs[nvecs] = make_vector(ctx, path2, (xj2 - xj1 > 1), 0,
+                                 path2 + subdirpos, 1);
        for (i = 0; i <= MAXCOLOUR; i++)
            vecs[0]->sizes[i] -= vecs[nvecs]->sizes[i];
        nvecs++;