Diff options
Diffstat (limited to '')
-rw-r--r--source/ui-tree.c118
1 file changed, 28 insertions, 90 deletions
diff --git a/source/ui-tree.c b/source/ui-tree.c
index 95ff337..aff4f0f 100644
--- a/source/ui-tree.c
+++ b/source/ui-tree.c
@@ -38,7 +38,7 @@ struct ls_entry {
};
struct walk_tree_context {
- char *rev;
+ const char *rev;
char *match_path;
enum walk_state state;
struct ls_entry *entries;
@@ -54,38 +54,19 @@ struct only_child {
size_t count;
};
-static void add_linenumber(struct strbuf *numbers, size_t lineno)
-{
- strbuf_addf(numbers, "<a id='n%zu' href='#n%zu'>%zu</a>\n", lineno, lineno, lineno);
-}
-
-/*
- * The anchors are handed over in batches rather than a write per line, and
- * never built whole, which would come to several times the blob's size.
- */
static void print_linenumbers(const char *buf, size_t size)
{
- struct strbuf numbers = STRBUF_INIT;
- size_t lineno = 0, idx = 0;
+ size_t lines = 0, idx;
if (size) {
- add_linenumber(&numbers, ++lineno);
-
+ lines = 1;
// The newline that ends the last line must not open a line of
- // its own, so the final byte is left out of the scan.
- while (idx < size - 1) {
- if (buf[idx] == '\n') {
- add_linenumber(&numbers, ++lineno);
- if (numbers.len >= HTML_BATCH) {
- html_raw(numbers.buf, numbers.len);
- strbuf_reset(&numbers);
- }
- }
- idx++;
- }
- html_raw(numbers.buf, numbers.len);
+ // its own, so the final byte is left out of the count.
+ for (idx = 0; idx < size - 1; idx++)
+ if (buf[idx] == '\n')
+ lines++;
}
- strbuf_release(&numbers);
+ cgit_print_line_anchors(1, lines);
}
static void print_text_buffer(const char *filename, char *buf, size_t size)
@@ -100,20 +81,14 @@ static void print_text_buffer(const char *filename, char *buf, size_t size)
html("<tr>\n");
}
+ html("<td class='lines'><pre><code>");
if (ctx.repo->source_filter) {
- char *filter_arg = xstrdup(filename);
-
- html("<td class='lines'><pre><code>");
- cgit_open_filter(ctx.repo->source_filter, filter_arg);
+ cgit_open_filter(ctx.repo->source_filter, filename);
html_raw(buf, size);
cgit_close_filter(ctx.repo->source_filter);
- free(filter_arg);
- html("</code></pre></td></tr></table>\n");
- return;
+ } else {
+ html_blob_txt(buf, size);
}
-
- html("<td class='lines'><pre><code>");
- html_blob_txt(buf, size);
html("</code></pre></td></tr></table>\n");
}
@@ -231,8 +206,8 @@ static int only_child_cb(const struct object_id *oid, struct strbuf *base UNUSED
return 0;
}
-static void print_dir_chain(const struct object_id *oid, char *name, char *rev,
- struct strbuf *fullpath)
+static void print_dir_chain(const struct object_id *oid, const char *name,
+ const char *rev, struct strbuf *fullpath)
{
size_t initial_length = fullpath->len;
struct tree *tree;
@@ -254,7 +229,7 @@ static void print_dir_chain(const struct object_id *oid, char *name, char *rev,
tree = lookup_tree(the_repository, &child.oid);
if (!tree)
- return;
+ break;
free(child.name);
child.name = NULL;
@@ -270,13 +245,13 @@ static void print_dir_chain(const struct object_id *oid, char *name, char *rev,
name = child.name;
}
+ free(child.name);
strbuf_setlen(fullpath, initial_length);
}
-static void print_ls_row(const struct object_id *oid, const char *pathname,
+static void print_ls_row(const struct object_id *oid, const char *name,
unsigned mode, struct walk_tree_context *walk)
{
- char *name;
struct strbuf fullpath = STRBUF_INIT;
struct strbuf linkpath = STRBUF_INIT;
struct strbuf class = STRBUF_INIT;
@@ -284,7 +259,6 @@ static void print_ls_row(const struct object_id *oid, const char *pathname,
size_t size = 0;
char *buf;
- name = xstrdup(pathname);
strbuf_addf(&fullpath, "%s%s%s", ctx.qry.path ? ctx.qry.path : "", ctx.qry.path ? "/" : "", name);
if (!S_ISGITLINK(mode)) {
@@ -314,7 +288,7 @@ static void print_ls_row(const struct object_id *oid, const char *pathname,
} else if (S_ISDIR(mode)) {
print_dir_chain(oid, name, walk->rev, &fullpath);
} else {
- char *ext = strrchr(name, '.');
+ const char *ext = strrchr(name, '.');
strbuf_addstr(&class, "ls-blob");
// The extension becomes a class a stylesheet can pick files out
@@ -366,7 +340,6 @@ static void print_ls_row(const struct object_id *oid, const char *pathname,
html("</td></tr>\n");
cleanup:
- free(name);
strbuf_release(&fullpath);
strbuf_release(&class);
}
@@ -435,25 +408,6 @@ static void ls_tail(void)
cgit_print_layout_end();
}
-static void ls_tree(const struct object_id *oid, struct walk_tree_context *walk)
-{
- struct tree *tree;
- struct pathspec paths = {
- .nr = 0
- };
-
- tree = parse_tree_indirect(oid);
- if (!tree) {
- cgit_print_error_page(404, "Not Found", "Not a tree object: %s", oid_to_hex(oid));
- return;
- }
-
- ls_head();
- read_tree(the_repository, tree, &paths, ls_item, walk);
- ls_flush(walk);
- ls_tail();
-}
-
static int walk_tree(const struct object_id *oid, struct strbuf *base,
const char *pathname, unsigned mode, void *data)
{
@@ -493,18 +447,8 @@ void cgit_print_tree(const char *rev, char *path)
{
struct object_id oid;
struct commit *commit;
- int path_len = path ? strlen(path) : 0;
- // nowildcard_len matches len so git treats the path as literal rather
- // than as a glob.
- struct pathspec_item path_items = {
- .match = path,
- .len = path_len,
- .nowildcard_len = path_len
- };
- struct pathspec paths = {
- .nr = path ? 1 : 0,
- .items = &path_items
- };
+ struct pathspec_item path_item;
+ struct pathspec paths = { 0 };
struct walk_tree_context walk = {
.match_path = path,
.state = WALK_LOOKING
@@ -513,22 +457,19 @@ void cgit_print_tree(const char *rev, char *path)
if (!rev)
rev = ctx.qry.head;
- if (repo_get_oid(the_repository, rev, &oid)) {
- cgit_print_error_page(404, "Not Found", "Bad object id: %s", rev);
- return;
- }
- commit = lookup_commit_reference(the_repository, &oid);
- if (!commit || repo_parse_commit(the_repository, commit)) {
- cgit_print_error_page(404, "Not Found", "Not a commit: %s", rev);
+ commit = cgit_get_commit(rev, &oid);
+ if (!commit)
return;
- }
- walk.rev = xstrdup(rev);
+ walk.rev = rev;
+ cgit_literal_pathspec(&paths, &path_item, path);
if (!path) {
+ // The walk is never handed an entry for the top of the tree
+ // itself, so the listing it would have opened is opened here.
cgit_prefix_title("tree");
- ls_tree(get_commit_tree_oid(commit), &walk);
- goto cleanup;
+ walk.state = WALK_LISTING;
+ ls_head();
}
read_tree(the_repository, repo_get_commit_tree(the_repository, commit), &paths, walk_tree, &walk);
@@ -542,7 +483,4 @@ void cgit_print_tree(const char *rev, char *path)
}
// WALK_ERROR_SHOWN is left alone, since the error page print_object
// put out is already complete.
-
-cleanup:
- free(walk.rev);
}