X-Git-Url: https://gitweb.ps.run/ps-cgit/blobdiff_plain/6b5b655f6d2449fe33d8f48f6e98d5e421bf3ff9..5b1f42ffeec7e315fc4fcff5145e5b0adca30715:/ui-blame.c diff --git a/ui-blame.c b/ui-blame.c index 62647a8..b118a81 100644 --- a/ui-blame.c +++ b/ui-blame.c @@ -41,37 +41,55 @@ static char *emit_suspect_detail(struct blame_origin *suspect) return strbuf_detach(&detail, NULL); } -static void emit_blame_entry(struct blame_scoreboard *sb, - struct blame_entry *ent) +static void emit_blame_entry_hash(struct blame_entry *ent) { struct blame_origin *suspect = ent->suspect; struct object_id *oid = &suspect->commit->object.oid; - const char *numberfmt = "%1$d\n"; - const char *cp, *cpend; + unsigned long line = 0; char *detail = emit_suspect_detail(suspect); - - html(""); + html(""); cgit_commit_link(find_unique_abbrev(oid->hash, DEFAULT_ABBREV), detail, NULL, ctx.qry.head, oid_to_hex(oid), suspect->path); - html("\n"); - + html(""); free(detail); - if (ctx.cfg.enable_tree_linenumbers) { - unsigned long lineno = ent->lno; - html("
");
-		while (lineno < ent->lno + ent->num_lines)
-			htmlf(numberfmt, ++lineno);
-		html("
\n"); - } + while (line++ < ent->num_lines) + html("\n"); +} - cp = blame_nth_line(sb, ent->lno); - cpend = blame_nth_line(sb, ent->lno + ent->num_lines); +static void emit_blame_entry_linenumber(struct blame_entry *ent) +{ + const char *numberfmt = "%1$d\n"; - html("
");
-	html_ntxt(cp, cpend - cp);
-	html("
\n"); + unsigned long lineno = ent->lno; + while (lineno < ent->lno + ent->num_lines) + htmlf(numberfmt, ++lineno); +} + +static void emit_blame_entry_line_background(struct blame_scoreboard *sb, + struct blame_entry *ent) +{ + unsigned long line; + size_t len, maxlen = 2; + const char* pos, *endpos; + + for (line = ent->lno; line < ent->lno + ent->num_lines; line++) { + html("\n"); + pos = blame_nth_line(sb, line); + endpos = blame_nth_line(sb, line + 1); + len = 0; + while (pos < endpos) { + len++; + if (*pos++ == '\t') + len = (len + 7) & ~7; + } + if (len > maxlen) + maxlen = len; + } + + for (len = 0; len < maxlen - 1; len++) + html(" "); } struct walk_tree_context { @@ -84,6 +102,7 @@ static void print_object(const unsigned char *sha1, const char *path, const char *basename, const char *rev) { enum object_type type; + char *buf; unsigned long size; struct argv_array rev_argv = ARGV_ARRAY_INIT; struct rev_info revs; @@ -98,6 +117,13 @@ static void print_object(const unsigned char *sha1, const char *path, return; } + buf = read_sha1_file(sha1, &type, &size); + if (!buf) { + cgit_print_error_page(500, "Internal server error", + "Error reading object %s", sha1_to_hex(sha1)); + return; + } + argv_array_push(&rev_argv, "blame"); argv_array_push(&rev_argv, rev); init_revisions(&revs, NULL); @@ -128,20 +154,68 @@ static void print_object(const unsigned char *sha1, const char *path, htmlf("
blob size (%ldKB)" " exceeds display size limit (%dKB).
", size / 1024, ctx.cfg.max_blob_size); - return; + goto cleanup; } - html(""); + html("
\n\n"); + + /* Commit hashes */ + html("\n"); + + /* Line numbers */ + if (ctx.cfg.enable_tree_linenumbers) { + html("\n"); + } + + html("
"); + for (ent = sb.ent; ent; ent = ent->next) { + html("
");
+		emit_blame_entry_hash(ent);
+		html("
"); + } + html("
"); + for (ent = sb.ent; ent; ent = ent->next) { + html("
");
+			emit_blame_entry_linenumber(ent);
+			html("
"); + } + html("
"); + + /* Colored bars behind lines */ + html("
"); for (ent = sb.ent; ent; ) { struct blame_entry *e = ent->next; - emit_blame_entry(&sb, ent); + html("
");
+		emit_blame_entry_line_background(&sb, ent);
+		html("
"); free(ent); ent = e; } - html("
\n"); + html(""); + free((void *)sb.final_buf); + /* Lines */ + html("
");
+	if (ctx.repo->source_filter) {
+		char *filter_arg = xstrdup(basename);
+		cgit_open_filter(ctx.repo->source_filter, filter_arg);
+		html_raw(buf, size);
+		cgit_close_filter(ctx.repo->source_filter);
+		free(filter_arg);
+	} else {
+		html_txt(buf);
+	}
+	html("
"); + + html("\n"); + + html("\n\n"); + cgit_print_layout_end(); + +cleanup: + free(buf); } static int walk_tree(const unsigned char *sha1, struct strbuf *base,