]> git.armaanb.net Git - stagit.git/blobdiff - stagit.c
more verbose errors: show which file failed on open
[stagit.git] / stagit.c
index d9832945177342903d3ff2696ab6d4e86a6b03ed..43cd2ef605cbbf537a8052dee3ecd7fbd55d083a 100644 (file)
--- a/stagit.c
+++ b/stagit.c
@@ -46,11 +46,6 @@ struct commitinfo {
        size_t ndeltas;
 };
 
-/* summary length (bytes) in the log */
-static const unsigned summarylen = 70;
-/* display line count or file size in file tree index */
-static const int showlinecount = 1;
-
 static git_repository *repo;
 
 static const char *relpath = "";
@@ -110,12 +105,10 @@ commitinfo_getstats(struct commitinfo *ci)
                err(1, "calloc");
 
        for (i = 0; i < ndeltas; i++) {
+               if (git_patch_from_diff(&patch, ci->diff, i))
+                       goto err;
                if (!(di = calloc(1, sizeof(struct deltainfo))))
                        err(1, "calloc");
-               if (git_patch_from_diff(&patch, ci->diff, i)) {
-                       git_patch_free(patch);
-                       goto err;
-               }
                di->patch = patch;
                ci->deltas[i] = di;
 
@@ -178,6 +171,7 @@ commitinfo_free(struct commitinfo *ci)
        git_tree_free(ci->parent_tree);
        git_commit_free(ci->commit);
        git_commit_free(ci->parent);
+       free(ci);
 }
 
 struct commitinfo *
@@ -214,14 +208,11 @@ commitinfo_getbyoid(const git_oid *id)
        opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH;
        if (git_diff_tree_to_tree(&(ci->diff), repo, ci->parent_tree, ci->commit_tree, &opts))
                goto err;
-       if (commitinfo_getstats(ci) == -1)
-               goto err;
 
        return ci;
 
 err:
        commitinfo_free(ci);
-       free(ci);
 
        return NULL;
 }
@@ -232,7 +223,7 @@ efopen(const char *name, const char *flags)
        FILE *fp;
 
        if (!(fp = fopen(name, flags)))
-               err(1, "fopen");
+               err(1, "fopen: '%s'", name);
 
        return fp;
 }
@@ -247,7 +238,7 @@ xmlencode(FILE *fp, const char *s, size_t len)
                switch(*s) {
                case '<':  fputs("&lt;",   fp); break;
                case '>':  fputs("&gt;",   fp); break;
-               case '\'': fputs("&apos;", fp); break;
+               case '\'': fputs("&#39;",  fp); break;
                case '&':  fputs("&amp;",  fp); break;
                case '"':  fputs("&quot;", fp); break;
                default:   fputc(*s, fp);
@@ -299,7 +290,7 @@ printtime(FILE *fp, const git_time *intime)
        t = (time_t)intime->time + (intime->offset * 60);
        if (!(intm = gmtime(&t)))
                return;
-       strftime(out, sizeof(out), "%a %b %e %H:%M:%S", intm);
+       strftime(out, sizeof(out), "%a, %e %b %Y %H:%M:%S", intm);
        if (intime->offset < 0)
                fprintf(fp, "%s -%02d%02d", out,
                            -(intime->offset) / 60, -(intime->offset) % 60);
@@ -377,28 +368,31 @@ writefooter(FILE *fp)
 int
 writeblobhtml(FILE *fp, const git_blob *blob)
 {
-       off_t i;
-       size_t n = 0;
-       char *nfmt = "<a href=\"#l%d\" id=\"l%d\">%d</a>\n";
+       size_t n = 0, i, prev;
+       const char *nfmt = "<a href=\"#l%d\" class=\"line\" id=\"l%d\">%7d</a> ";
        const char *s = git_blob_rawcontent(blob);
        git_off_t len = git_blob_rawsize(blob);
 
-       fputs("<table id=\"blob\"><tr><td class=\"num\"><pre>\n", fp);
+       fputs("<pre id=\"blob\">\n", fp);
 
-       if (len) {
-               n++;
-               fprintf(fp, nfmt, n, n, n);
-               for (i = 0; i < len - 1; i++) {
-                       if (s[i] == '\n') {
-                               n++;
-                               fprintf(fp, nfmt, n, n, n);
-                       }
+       if (len > 0) {
+               for (i = 0, prev = 0; i < (size_t)len; i++) {
+                       if (s[i] != '\n')
+                               continue;
+                       n++;
+                       fprintf(fp, nfmt, n, n, n);
+                       xmlencode(fp, &s[prev], i - prev + 1);
+                       prev = i + 1;
+               }
+               /* trailing data */
+               if ((len - prev) > 0) {
+                       n++;
+                       fprintf(fp, nfmt, n, n, n);
+                       xmlencode(fp, &s[prev], len - prev);
                }
        }
 
-       fputs("</pre></td><td><pre>\n", fp);
-       xmlencode(fp, s, (size_t)len);
-       fputs("</pre></td></tr></table>\n", fp);
+       fputs("</pre>\n", fp);
 
        return n;
 }
@@ -485,7 +479,7 @@ printshowfile(FILE *fp, struct commitinfo *ci)
                fwrite(&linestr[add], 1, del, fp);
                fputs("</span></td></tr>\n", fp);
        }
-       fprintf(fp, "</table>%zu file%s changed, %zu insertion%s(+), %zu deletion%s(-)\n",
+       fprintf(fp, "</table></pre><pre>%zu file%s changed, %zu insertion%s(+), %zu deletion%s(-)\n",
                ci->filecount, ci->filecount == 1 ? "" : "s",
                ci->addcount,  ci->addcount  == 1 ? "" : "s",
                ci->delcount,  ci->delcount  == 1 ? "" : "s");
@@ -536,30 +530,23 @@ printshowfile(FILE *fp, struct commitinfo *ci)
 void
 writelogline(FILE *fp, struct commitinfo *ci)
 {
-       size_t len;
-
        fputs("<tr><td>", fp);
        if (ci->author)
                printtimeshort(fp, &(ci->author->when));
        fputs("</td><td>", fp);
        if (ci->summary) {
                fprintf(fp, "<a href=\"%scommit/%s.html\">", relpath, ci->oid);
-               if ((len = strlen(ci->summary)) > summarylen) {
-                       xmlencode(fp, ci->summary, summarylen - 1);
-                       fputs("…", fp);
-               } else {
-                       xmlencode(fp, ci->summary, len);
-               }
+               xmlencode(fp, ci->summary, strlen(ci->summary));
                fputs("</a>", fp);
        }
        fputs("</td><td>", fp);
        if (ci->author)
                xmlencode(fp, ci->author->name, strlen(ci->author->name));
-       fputs("</td><td class=\"num\">", fp);
+       fputs("</td><td class=\"num\" align=\"right\">", fp);
        fprintf(fp, "%zu", ci->filecount);
-       fputs("</td><td class=\"num\">", fp);
+       fputs("</td><td class=\"num\" align=\"right\">", fp);
        fprintf(fp, "+%zu", ci->addcount);
-       fputs("</td><td class=\"num\">", fp);
+       fputs("</td><td class=\"num\" align=\"right\">", fp);
        fprintf(fp, "-%zu", ci->delcount);
        fputs("</td></tr>\n", fp);
 }
@@ -586,6 +573,9 @@ writelog(FILE *fp, const git_oid *oid)
                        break;
                if (!(ci = commitinfo_getbyoid(&id)))
                        break;
+               /* lookup stats: only required here */
+               if (commitinfo_getstats(ci) == -1)
+                       goto err;
 
                writelogline(fp, ci);
                if (cachefile)
@@ -607,6 +597,7 @@ writelog(FILE *fp, const git_oid *oid)
                        writefooter(fpfile);
                        fclose(fpfile);
                }
+err:
                commitinfo_free(ci);
        }
        git_revwalk_free(w);
@@ -696,7 +687,7 @@ writeatom(FILE *fp)
        }
        git_revwalk_free(w);
 
-       fputs("</feed>", fp);
+       fputs("</feed>\n", fp);
 
        return 0;
 }
@@ -834,8 +825,8 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
                        fputs(filemode(git_tree_entry_filemode(entry)), fp);
                        fprintf(fp, "</td><td><a href=\"%s%s\">", relpath, filepath);
                        xmlencode(fp, entrypath, strlen(entrypath));
-                       fputs("</a></td><td class=\"num\">", fp);
-                       if (showlinecount && lc > 0)
+                       fputs("</a></td><td class=\"num\" align=\"right\">", fp);
+                       if (lc > 0)
                                fprintf(fp, "%dL", lc);
                        else
                                fprintf(fp, "%juB", (uintmax_t)filesize);
@@ -846,7 +837,7 @@ writefilestree(FILE *fp, git_tree *tree, const char *path)
                                relpath);
                        xmlencode(fp, entrypath, strlen(entrypath));
                        git_submodule_free(module);
-                       fputs("</a></td><td class=\"num\"></td></tr>\n", fp);
+                       fputs("</a></td><td class=\"num\" align=\"right\"></td></tr>\n", fp);
                }
        }
 
@@ -861,7 +852,8 @@ writefiles(FILE *fp, const git_oid *id)
        int ret = -1;
 
        fputs("<table id=\"files\"><thead>\n<tr>"
-             "<td>Mode</td><td>Name</td><td class=\"num\">Size</td>"
+             "<td><b>Mode</b></td><td><b>Name</b></td>"
+             "<td class=\"num\" align=\"right\"><b>Size</b></td>"
              "</tr>\n</thead><tbody>\n", fp);
 
        if (!git_commit_lookup(&commit, repo, id) &&
@@ -945,9 +937,12 @@ writerefs(FILE *fp)
 
                        /* print header if it has an entry (first). */
                        if (++count == 1) {
-                               fprintf(fp, "<h2>%s</h2><table id=\"%s\"><thead>\n<tr><td>Name</td>"
-                                     "<td>Last commit date</td><td>Author</td>\n</tr>\n</thead><tbody>\n",
-                                     titles[j], ids[j]);
+                               fprintf(fp, "<h2>%s</h2><table id=\"%s\">"
+                                       "<thead>\n<tr><td><b>Name</b></td>"
+                                       "<td><b>Last commit date</b></td>"
+                                       "<td><b>Author</b></td>\n</tr>\n"
+                                       "</thead><tbody>\n",
+                                        titles[j], ids[j]);
                        }
 
                        relpath = "";
@@ -1099,11 +1094,13 @@ main(int argc, char *argv[])
        /* log for HEAD */
        fp = efopen("log.html", "w");
        relpath = "";
-       mkdir("commit", 0755);
+       mkdir("commit", S_IRWXU | S_IRWXG | S_IRWXO);
        writeheader(fp, "Log");
-       fputs("<table id=\"log\"><thead>\n<tr><td>Date</td><td>Commit message</td>"
-                 "<td>Author</td><td class=\"num\">Files</td><td class=\"num\">+</td>"
-                 "<td class=\"num\">-</td></tr>\n</thead><tbody>\n", fp);
+       fputs("<table id=\"log\"><thead>\n<tr><td><b>Date</b></td>"
+             "<td><b>Commit message</b></td>"
+             "<td><b>Author</b></td><td class=\"num\" align=\"right\"><b>Files</b></td>"
+             "<td class=\"num\" align=\"right\"><b>+</b></td>"
+             "<td class=\"num\" align=\"right\"><b>-</b></td></tr>\n</thead><tbody>\n", fp);
 
        if (cachefile) {
                /* read from cache file (does not need to exist) */
@@ -1118,7 +1115,7 @@ main(int argc, char *argv[])
                if ((fd = mkstemp(tmppath)) == -1)
                        err(1, "mkstemp");
                if (!(wcachefp = fdopen(fd, "w")))
-                       err(1, "fdopen");
+                       err(1, "fdopen: '%s'", tmppath);
                /* write last commit id (HEAD) */
                git_oid_tostr(buf, sizeof(buf), head);
                fprintf(wcachefp, "%s\n", buf);