git home / emma home
logo

sgw

Static git web. Emma's fork of stagit.
git clone https://git.y1.nz/archives/sgw.tar.gz
README | Files | Log | Refs | LICENSE

commit 42eae3e1bbc5085115e948f426e6e9a52e4d2a76
parent 8684421e547f08888751ed14042b8063eadc1e45
Author: Emma Weaver <emma@waeaves.com>
Date:   Wed, 20 May 2026 00:26:21 -0400

Improved sizes printing, rewrote mkdirp without strlcpy

Diffstat:
MTODO6++++--
Mstagit.c147+++++++++++++++++++++++++++++++++----------------------------------------------
Mstyle.css31+++++++------------------------
3 files changed, 72 insertions(+), 112 deletions(-)

diff --git a/TODO b/TODO @@ -20,8 +20,10 @@ [ ] add lines of code totals on files page [x] add lines of code on each file's page [x] show line/byte totals for each directory -[ ] tweak paths that start with dots, so that they don't get hidden or 403'd (?) -[ ] handle missing decorations (desc/logo/favicon) better +[ ] tweak paths that start with dots, so that they don't get hidden or 403'd + - put parentheses around the dirnames in the urls +[ ] while writing log, only print links to files whose pages exist +[ ] add backlinks on files ---END NEW FEATURES--- [ ] Remove globals diff --git a/stagit.c b/stagit.c @@ -72,7 +72,6 @@ static git_repository *repo; /* flags + arguments */ static const char *baseurl = ""; /* base URL to make absolute RSS/Atom URI */ -static const char *relpath = ""; static const char *repodir; static char *name = ""; @@ -480,17 +479,23 @@ put_xml_line(FILE *fp, const char *s, size_t len) int mkdirp(const char *path) { - char tmp[PATH_MAX], *p; + const char *p; + char tmp[PATH_MAX]; + char *t; - if (strlcpy(tmp, path, sizeof(tmp)) >= sizeof(tmp)) - errx(1, "path truncated: '%s'", path); - for (p = tmp + (tmp[0] == '/'); *p; p++) { - if (*p != '/') + for(t = tmp, p = path; *p != '\0'; *p++, *t++) { + if (*p != '/') { + *t = *p; continue; - *p = '\0'; - if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) + } + + *t = '\0'; + if ( + mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && + errno != EEXIST + ) return -1; - *p = '/'; + *t = '/'; } return 0; } @@ -567,7 +572,7 @@ printtimeshort(FILE *fp, const git_time *intime) char * put_absolute_path(FILE *fp, const char * path) { - fprintf(fp, "/%s%s", relpath, path); + fprintf(fp, "%s/%s", baseurl, path); } void @@ -612,23 +617,21 @@ put_header(FILE *fp, const char *title) SPUTF(fp, "\" />" "\n"); SPUTF(fp, "</head>" "\n" "<body>" "\n"); - // TODO handle backlink using config.h - SPUTF(fp, "<p><a href=\""); - put_absolute_path(fp, "files.html"); - SPUTF(fp, "\">home</a></p>" "\n"); - - SPUTF(fp, "<table><tr><td>"); + SPUTF(fp, "<table>" "<tr><td>"); + /* fprintf(fp, "<a href=\""); - put_absolute_path(fp, ""); // TODO links to site root? + put_absolute_path(fp, ""); // TODO how to handle? ./.logo.png? SPUTF(fp, "\"><img src=\""); put_absolute_path(fp, "logo.png"); SPUTF(fp, "\" alt=\"\" width=\"32\" height=\"32\" /></a>"); + */ - SPUTF(fp, "</td><td><h1>"); - put_xml(fp, stripped_name, strlen(stripped_name)); - SPUTF(fp, "</h1><span class=\"desc\">"); + SPUTF(fp, "</td><td>" "<h1>"); + if (stripped_name[0] == '\0') SPUTF(fp, "untitled"); + else put_xml(fp, stripped_name, strlen(stripped_name)); + SPUTF(fp, "</h1>" "<span class=\"desc\">"); put_xml(fp, description, strlen(description)); - SPUTF(fp, "</span></td></tr>"); + SPUTF(fp, "</span>" "</td></tr>"); if (cloneurl[0]) { SPUTF(fp, "<tr class=\"url\"><td></td><td>git clone <a href=\""); put_xml(fp, cloneurl, strlen(cloneurl)); /* not percent-encoded */ @@ -687,8 +690,8 @@ size_t put_file_html(FILE *fp, const git_blob *blob) { size_t n = 0, i, len, prev; - // TODO use spaces + pre to right-align the line numbers, instead of css - const char *number_format = "<a href=\"#l%zu\" class=\"line\" id=\"l%zu\">%7zu </a>"; + const char *number_format = + "<a href=\"#l%zu\" class=\"line\" id=\"l%zu\">%7zu </a>"; const char *s = git_blob_rawcontent(blob); len = git_blob_rawsize(blob); @@ -721,13 +724,13 @@ void print_commit(FILE *fp, struct CommitInfo *ci) { SPUTF(fp, "<b>commit</b> <a href=\""); - put_absolute_path(fp, "commit/"); + put_absolute_path(fp, "commits/"); fprintf(fp, "%s.html", ci->oid); fprintf(fp, "\">%s</a>" "\n", ci->oid); if (ci->parentoid[0]) SPUTF(fp, "<b>parent</b> <a href=\""); - put_absolute_path(fp, "commit/"); + put_absolute_path(fp, "commits/"); fprintf(fp, "%s.html", ci->parentoid); fprintf(fp, "\">%s</a>" "\n", ci->parentoid); @@ -907,7 +910,7 @@ put_log_line(FILE *fp, struct CommitInfo *ci) fputs("</td><td>", fp); if (ci->summary) { SPUTF(fp, "<a href=\""); - put_absolute_path(fp, "commit/"); + put_absolute_path(fp, "commits/"); fprintf(fp, "%s.html", ci->oid); SPUTF(fp, "\">"); put_xml(fp, ci->summary, strlen(ci->summary)); @@ -940,15 +943,13 @@ write_log(FILE *fp, const git_oid *oid) git_revwalk_push(w, oid); while (!git_revwalk_next(&id, w)) { - relpath = ""; - if (cachefile && !memcmp(&id, &lastoid, sizeof(id))) break; git_oid_tostr(oidstr, sizeof(oidstr), &id); - r = snprintf(path, sizeof(path), "commit/%s.html", oidstr); + r = snprintf(path, sizeof(path), "commits/%s.html", oidstr); if (r < 0 || (size_t)r >= sizeof(path)) - errx(1, "path truncated: 'commit/%s.html'", oidstr); + errx(1, "path truncated: 'commits/%s.html'", oidstr); r = access(path, F_OK); /* optimization: if there are no log lines to write and @@ -976,7 +977,6 @@ write_log(FILE *fp, const git_oid *oid) /* check if file exists if so skip it */ if (r) { - relpath = "../"; fpfile = efopen(path, "w"); put_header(fpfile, ci->summary); @@ -1002,8 +1002,6 @@ err: remcommits ); - relpath = ""; - return 0; } @@ -1073,8 +1071,6 @@ write_log_cached(FILE *fp, const git_oid *head) void put_log_html(FILE *fp, const git_oid *head) { - relpath = ""; - mkdir("commit", S_IRWXU | S_IRWXG | S_IRWXO); put_header(fp, "Log"); fputs( "<table id=\"log\"><thead>" "\n" @@ -1125,7 +1121,7 @@ print_commit_atom(FILE *fp, struct CommitInfo *ci, const char *tag) } fprintf( fp, - "<link rel=\"alternate\" type=\"text/html\" href=\"%scommit/%s.html\" />\n", + "<link rel=\"alternate\" type=\"text/html\" href=\"%scommits/%s.html\" />\n", baseurl, ci->oid ); @@ -1226,9 +1222,10 @@ write_binary_file(const char *filename, git_blob *blob) { } void -put_size(FILE *fp, size_t size) +put_size(FILE *fp, size_t size, int fixed) { int order = 0; + int decimal; if (size == 0) { fprintf(fp, " - "); @@ -1237,10 +1234,14 @@ put_size(FILE *fp, size_t size) while (size > 1000) { order++; + decimal = (size / 100) % 10; size /= 1000; } - fprintf(fp, "%3zu%c", size, orders[order]); + if (size < 10 && order > 0) fprintf(fp, "%1zu.%1d", size, decimal); + else fprintf(fp, fixed ? "%3zu" : "%zu", size); + + if (order != 0 || fixed) fprintf(fp, "%c", orders[order]); } size_t @@ -1258,16 +1259,6 @@ put_blob( FILE *fp; int is_binary; - if (strlcpy(tmp, filename, sizeof(tmp)) >= sizeof(tmp)) - errx(1, "path truncated: '%s'", filename); - - // wtf does this do.... - for (p = filename, tmp[0] = '\0'; *p; p++) { - if (*p == '/' && strlcat(tmp, "../", sizeof(tmp)) >= sizeof(tmp)) - errx(1, "path truncated: '../%s'", tmp); - } - relpath = tmp; - is_binary = git_blob_is_binary((git_blob *)obj); const char *file_url = is_binary ? entryname : ""; @@ -1275,11 +1266,7 @@ put_blob( put_header(fp, entryname); fprintf(fp, "<p>"); put_xml(fp, entrypath, strlen(entrypath)); - CPUT(fp, ' '); - put_size(fp, 0); - CPUT(fp, ' '); - put_size(fp, bytes); - SPUTF(fp, "B</p>"); + SPUTF(fp, "</p>"); if (is_binary) { fprintf( @@ -1300,8 +1287,6 @@ put_blob( check_file_error(fp, filename, 'w'); fclose(fp); - relpath = ""; - return lines; } @@ -1370,9 +1355,9 @@ put_filetree_file_line( SPUTF(fp, "\">"); put_xml(fp, entryname, strlen(entryname)); SPUTF(fp, "</a></td><td class=\"num\" align=\"right\">"); - put_size(fp, lines); + put_size(fp, lines, 1); SPUTF(fp, "</td><td class=\"num\" align=\"right\">"); - put_size(fp, bytes); + put_size(fp, bytes, 1); SPUTF(fp, "</td></tr>\n"); return ret; } @@ -1394,9 +1379,9 @@ put_filetree_dir_line( SPUTF(fp, "\">"); put_xml(fp, title, strlen(title)); SPUTF(fp, "</a></td><td class=\"num\" align=\"right\">"); - put_size(fp, lines); + put_size(fp, lines, 1); SPUTF(fp, "</td><td class=\"num\" align=\"right\">"); - put_size(fp, bytes); + put_size(fp, bytes, 1); SPUTF(fp, "</td></tr>\n"); } @@ -1425,24 +1410,19 @@ void put_filetree_backlink_line(FILE *fp, const char *path) { /* need this here to allow recursion */ struct Weight write_filetree( - const char *filename, const char *path, + const char *filename, git_tree *tree ); struct Weight -put_entry_obj( - FILE *fp, - git_object *obj, - const git_tree_entry *entry, - char *entrypath, - const char *entryname -) { +put_entry_obj(FILE *fp, git_object *obj, const git_tree_entry *entry, char *entrypath, const char *entryname) +{ struct Weight ret; git_object_t obj_type = git_object_type(obj); char filename[PATH_MAX]; int r; - + /* filename = f("files/%s.html", entrypath) */ r = snprintf(filename, sizeof(filename), "files/%s.html", entrypath); if (r < 0 || (size_t) r >= sizeof(filename)) @@ -1451,7 +1431,7 @@ put_entry_obj( switch (obj_type) { case GIT_OBJ_TREE: /* NOTE: recurses */ - ret = write_filetree(filename, entrypath, (git_tree *) obj); + ret = write_filetree(entrypath, filename, (git_tree *) obj); put_filetree_dir_line( fp, entry, @@ -1484,20 +1464,15 @@ put_submodule_obj( ) { char oid[8]; - SPUTF(fp, "<tr><td>m---------</td><td><a href=\""); + SPUTF(fp, "<tr>" "<td>m---------</td>" "<td><a href=\""); put_absolute_path(fp, "files/.gitmodules.html"); SPUTF(fp, "\">"); put_xml(fp, entrypath, strlen(entrypath)); SPUTF(fp, "</a> @ "); git_oid_tostr(oid, sizeof(oid), git_tree_entry_id(entry)); put_xml(fp, oid, strlen(oid)); - SPUTF(fp, "</td><td class=\"num\" align=\"right\"></td></tr>" "\n"); -} - -void -put_entry() -{ - + SPUTF(fp, "</td>" "<td class=\"num\" align=\"right\"></td>" "\n"); + SPUTF(fp, "<td class=\"num\" align=\"right\"></td>" "</tr>" "\n"); } struct Weight @@ -1559,7 +1534,7 @@ put_filetree_dir_title(FILE *fp, const char *path) } struct Weight -write_filetree(const char *filename, const char *path, git_tree *tree) +write_filetree(const char *path, const char *filename, git_tree *tree) { FILE *fp; struct Weight ret; @@ -1567,7 +1542,7 @@ write_filetree(const char *filename, const char *path, git_tree *tree) fp = efopen(filename, "w"); put_header(fp, "Files"); - fprintf(fp, "<p>"); + SPUTF(fp, "<p>"); put_filetree_dir_title(fp, path); SPUTF(fp, "</p>"); @@ -1575,8 +1550,8 @@ write_filetree(const char *filename, const char *path, git_tree *tree) fp, "<table id=\"files\"><thead>" "\n" "<tr>" "<td><b>Mode</b></td><td><b>Name</b></td>" - "<td class=\"num\" align=\"right\"><b>L</b></td>" - "<td class=\"num\" align=\"right\"><b>B</b></td>" + "<td class=\"num\" align=\"right\"><b> L </b></td>" + "<td class=\"num\" align=\"right\"><b> B </b></td>" "</tr>" "\n" "</thead><tbody>" "\n" ); @@ -1586,9 +1561,9 @@ write_filetree(const char *filename, const char *path, git_tree *tree) SPUTF(fp, "</tbody></table>"); SPUTF(fp, "<p>Totals: "); - put_size(fp, ret.lines); + put_size(fp, ret.lines, 0); SPUTF(fp, "L "); - put_size(fp, ret.bytes); + put_size(fp, ret.bytes, 0); SPUTF(fp, "B</p>"); put_footer(fp); @@ -1610,7 +1585,7 @@ walk_git_tree(const git_oid *id) has_files = !git_commit_lookup(&commit, repo, id) && !git_commit_tree(&tree, commit); - write_filetree("files.html", "", has_files ? tree : NULL); + write_filetree("", "files.html", has_files ? tree : NULL); git_commit_free(commit); git_tree_free(tree); @@ -1663,7 +1638,7 @@ write_refs(FILE *fp) put_xml(fp, ci->author->name, strlen(ci->author->name)); fputs("</td></tr>\n", fp); } - /* table footer */ + if (count) fputs("</tbody></table><br/>\n", fp); @@ -1724,7 +1699,7 @@ usage(char *argv0) fprintf( stderr, "usage: %s [-c cachefile | -l commits] " - "[-u baseurl] repodir\n", + "[-u baseurl] repodir" "\n", argv0 ); exit(1); diff --git a/style.css b/style.css @@ -13,7 +13,7 @@ img, h1, h2 { } img, object { - border: 1px solid black; + border: 1px solid #ccc; } a { @@ -30,10 +30,7 @@ a:target { background-color: #ddf; } -a.d, -a.h, -a.i, -a.line { +a.d, a.h, a.i, a.line { text-decoration: none; } @@ -53,7 +50,7 @@ table td { #content table td { vertical-align: top; - white-space: pre-wrap; + white-space: pre; } #branches tr:hover td, @@ -82,18 +79,10 @@ table#diffstat { } #blob a { - border-right: 1px solid black; - margin-right: 5px; - padding-right: 5px; + margin-right: 10px; user-select: none; } -/* -table#blob { - border-collapse: collapse; -} -*/ - td.num { text-align: right; } @@ -117,20 +106,14 @@ pre a.h { color: #0072aa; /* blue */ } -.A, -span.i, -pre a.i { +.A, span.i, pre a.i { color: #00ba53; /* green */ } -.D, -span.d, -pre a.d { +.D, span.d, pre a.d { color: #ee3200; /* red */ } -pre a.h:hover, -pre a.i:hover, -pre a.d:hover { +pre a.h:hover, pre a.i:hover, pre a.d:hover { text-decoration: none; }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.