Diff options
Diffstat (limited to '')
| -rw-r--r-- | source/ui-tree.c | 118 |
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); } |
