| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | cgit.c | 5 | ||||
| -rw-r--r-- | cgit.css | 16 | ||||
| -rw-r--r-- | cgit.h | 8 | ||||
| -rw-r--r-- | shared.c | 3 | ||||
| -rw-r--r-- | ui-commit.c | 3 | ||||
| -rw-r--r-- | ui-tree.c | 194 | ||||
| -rw-r--r-- | ui-view.c | 55 |
8 files changed, 112 insertions, 174 deletions
@@ -14,7 +14,7 @@ CGIT_SCRIPT_NAME = cgit.cgi EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \ - ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \ + ui-summary.o ui-log.o ui-view.o ui-tree.o ui-commit.o ui-diff.o \ ui-snapshot.o ui-blob.o CFLAGS += -Wall @@ -97,11 +97,14 @@ static void cgit_print_repo_page(struct cacheitem *item) cgit_query_path, 1); break; case CMD_TREE: - cgit_print_tree(cgit_query_sha1, cgit_query_path); + cgit_print_tree(cgit_query_head, cgit_query_sha1, cgit_query_path); break; case CMD_COMMIT: cgit_print_commit(cgit_query_head); break; + case CMD_VIEW: + cgit_print_view(cgit_query_sha1, cgit_query_path); + break; case CMD_DIFF: cgit_print_diff(cgit_query_head, cgit_query_sha1, cgit_query_sha2, cgit_query_path); @@ -199,22 +199,10 @@ td.filemode { font-family: monospace; } -table.blob { - margin-top: 0.5em; - border-top: solid 1px black; -} - -table.blob td.no { - border-right: solid 1px black; - color: black; - background-color: #eee; - text-align: right; -} - -table.blob td.txt { +td.blob { white-space: pre; font-family: monospace; - padding-left: 0.5em; + background-color: white; } table.nowrap td { @@ -25,8 +25,9 @@ #define CMD_COMMIT 2 #define CMD_DIFF 3 #define CMD_TREE 4 -#define CMD_BLOB 5 -#define CMD_SNAPSHOT 6 +#define CMD_VIEW 5 +#define CMD_BLOB 6 +#define CMD_SNAPSHOT 7 /* @@ -214,8 +215,9 @@ extern void cgit_print_snapshot_start(const char *mimetype, extern void cgit_print_repolist(struct cacheitem *item); extern void cgit_print_summary(); extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path, int pager); +extern void cgit_print_view(const char *hex, char *path); extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); -extern void cgit_print_tree(const char *rev, char *path); +extern void cgit_print_tree(const char *rev, const char *hex, char *path); extern void cgit_print_commit(const char *hex); extern void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex, char *path); @@ -59,8 +59,7 @@ int htmlfd = 0; int cgit_get_cmd_index(const char *cmd) { - static char *cmds[] = {"log", "commit", "diff", "tree", "blob", - "snapshot", NULL}; + static char *cmds[] = {"log", "commit", "diff", "tree", "view", "blob", "snapshot", NULL}; int i; for(i = 0; cmds[i]; i++) diff --git a/ui-commit.c b/ui-commit.c index ed5384d..1d12bbb 100644 --- a/ui-commit.c +++ b/ui-commit.c @@ -182,7 +182,8 @@ void cgit_print_commit(const char *hex) cgit_print_date(info->committer_date, FMT_LONGDATE); html("</td></tr>\n"); html("<tr><th>tree</th><td colspan='2' class='sha1'><a href='"); - query = fmt("h=%s", sha1_to_hex(commit->object.sha1)); + query = fmt("h=%s&id=%s", sha1_to_hex(commit->object.sha1), + sha1_to_hex(commit->tree->object.sha1)); html_attr(cgit_pageurl(cgit_query_repo, "tree", query)); htmlf("'>%s</a></td></tr>\n", sha1_to_hex(commit->tree->object.sha1)); for (p = commit->parents; p ; p = p->next) { @@ -9,56 +9,14 @@ #include "cgit.h" char *curr_rev; -char *match_path; -int header = 0; -static void print_object(const unsigned char *sha1, char *path) -{ - enum object_type type; - unsigned char *buf; - unsigned long size, lineno, start, idx; - - type = sha1_object_info(sha1, &size); - if (type == OBJ_BAD) { - cgit_print_error(fmt("Bad object name: %s", - sha1_to_hex(sha1))); - return; - } - - buf = read_sha1_file(sha1, &type, &size); - if (!buf) { - cgit_print_error(fmt("Error reading object %s", - sha1_to_hex(sha1))); - return; - } - - html("<table class='blob'>\n"); - idx = 0; - start = 0; - lineno = 0; - while(idx < size) { - if (buf[idx] == '\n') { - buf[idx] = '\0'; - htmlf("<tr><td class='no'>%d</td><td class='txt'>", - ++lineno); - html_txt(buf + start); - html("</td></tr>\n"); - start = idx + 1; - } - idx++; - } - html("\n</td></tr>\n"); - html("</table>\n"); -} - - -static int ls_item(const unsigned char *sha1, const char *base, int baselen, - const char *pathname, unsigned int mode, int stage) +static int print_entry(const unsigned char *sha1, const char *base, + int baselen, const char *pathname, unsigned int mode, + int stage) { char *name; enum object_type type; unsigned long size = 0; - char *url, *qry; name = xstrdup(pathname); type = sha1_object_info(sha1, &size); @@ -68,10 +26,6 @@ static int ls_item(const unsigned char *sha1, const char *base, int baselen, sha1_to_hex(sha1)); return 0; } - qry = fmt("h=%s&path=%s%s%s", curr_rev, - cgit_query_path ? cgit_query_path : "", - cgit_query_path ? "/" : "", pathname); - url = cgit_pageurl(cgit_query_repo, "tree", qry); html("<tr><td class='filemode'>"); html_filemode(mode); html("</td><td "); @@ -82,133 +36,69 @@ static int ls_item(const unsigned char *sha1, const char *base, int baselen, sha1_to_hex(sha1))); } else if (S_ISDIR(mode)) { html("class='ls-dir'><a href='"); - html_attr(url); + html_attr(cgit_pageurl(cgit_query_repo, "tree", + fmt("h=%s&id=%s&path=%s%s/", + curr_rev, + sha1_to_hex(sha1), + cgit_query_path ? cgit_query_path : "", + pathname))); } else { html("class='ls-blob'><a href='"); - html_attr(url); + html_attr(cgit_pageurl(cgit_query_repo, "view", + fmt("h=%s&id=%s&path=%s%s", curr_rev, + sha1_to_hex(sha1), + cgit_query_path ? cgit_query_path : "", + pathname))); } htmlf("'>%s</a></td>", name); htmlf("<td class='filesize'>%li</td>", size); html("<td class='links'><a href='"); - qry = fmt("h=%s&path=%s%s%s", curr_rev, - cgit_query_path ? cgit_query_path : "", - cgit_query_path ? "/" : "", pathname); - url = cgit_pageurl(cgit_query_repo, "log", qry); - html_attr(url); - html("' class='button'>H</a></td>"); + html_attr(cgit_pageurl(cgit_query_repo, "log", + fmt("h=%s&path=%s%s", + curr_rev, + cgit_query_path ? cgit_query_path : "", + pathname))); + html("'>history</a></td>"); html("</tr>\n"); free(name); return 0; } -static void ls_head() -{ - html("<table class='list'>\n"); - html("<tr class='nohover'>"); - html("<th class='left'>Mode</th>"); - html("<th class='left'>Name</th>"); - html("<th class='right'>Size</th>"); - html("<th/>"); - html("</tr>\n"); - header = 1; -} - -static void ls_tail() -{ - if (!header) - return; - html("</table>\n"); - header = 0; -} - -static void ls_tree(const unsigned char *sha1, char *path) +void cgit_print_tree(const char *rev, const char *hex, char *path) { struct tree *tree; - - tree = parse_tree_indirect(sha1); - if (!tree) { - cgit_print_error(fmt("Not a tree object: %s", - sha1_to_hex(sha1))); - return; - } - - ls_head(); - read_tree_recursive(tree, "", 0, 1, NULL, ls_item); - ls_tail(); -} - - -static int walk_tree(const unsigned char *sha1, const char *base, int baselen, - const char *pathname, unsigned mode, int stage) -{ - static int state; - static char buffer[PATH_MAX]; - char *url; - - if (state == 0) { - memcpy(buffer, base, baselen); - strcpy(buffer+baselen, pathname); - url = cgit_pageurl(cgit_query_repo, "tree", - fmt("h=%s&path=%s", curr_rev, buffer)); - htmlf(" / <a href='"); - html_attr(url); - html("'>"); - html_txt(xstrdup(pathname)); - html("</a>"); - - if (strcmp(match_path, buffer)) - return READ_TREE_RECURSIVE; - - if (S_ISDIR(mode)) { - state = 1; - ls_head(); - return READ_TREE_RECURSIVE; - } else { - print_object(sha1, buffer); - return 0; - } - } - ls_item(sha1, base, baselen, pathname, mode, stage); - return 0; -} - - -/* - * Show a tree or a blob - * rev: the commit pointing at the root tree object - * path: path to tree or blob - */ -void cgit_print_tree(const char *rev, char *path) -{ unsigned char sha1[20]; struct commit *commit; - const char *paths[] = {path, NULL}; - - if (!rev) - rev = cgit_query_head; curr_rev = xstrdup(rev); - if (get_sha1(rev, sha1)) { - cgit_print_error(fmt("Invalid revision name: %s", rev)); - return; - } + get_sha1(rev, sha1); commit = lookup_commit_reference(sha1); if (!commit || parse_commit(commit)) { - cgit_print_error(fmt("Invalid commit reference: %s", rev)); + cgit_print_error(fmt("Invalid head: %s", rev)); return; } + if (!hex) + hex = sha1_to_hex(commit->tree->object.sha1); - html("path: <a href='"); - html_attr(cgit_pageurl(cgit_query_repo, "tree", fmt("h=%s", rev))); - html("'>root</a>"); - - if (path == NULL) { - ls_tree(commit->tree->object.sha1, NULL); + if (get_sha1_hex(hex, sha1)) { + cgit_print_error(fmt("Invalid object id: %s", hex)); + return; + } + tree = parse_tree_indirect(sha1); + if (!tree) { + cgit_print_error(fmt("Not a tree object: %s", hex)); return; } - match_path = path; - read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree); - ls_tail(); + html_txt(path); + html("<table class='list'>\n"); + html("<tr class='nohover'>"); + html("<th class='left'>Mode</th>"); + html("<th class='left'>Name</th>"); + html("<th class='right'>Size</th>"); + html("<th/>"); + html("</tr>\n"); + read_tree_recursive(tree, "", 0, 1, NULL, print_entry); + html("</table>\n"); } diff --git a/ui-view.c b/ui-view.c new file mode 100644 index 0000000..8873415 --- /dev/null +++ b/ui-view.c @@ -0,0 +1,55 @@ +/* ui-view.c: functions to output _any_ object, given it's sha1 + * + * Copyright (C) 2006 Lars Hjemli + * + * Licensed under GNU General Public License v2 + * (see COPYING for full license text) + */ + +#include "cgit.h" + +void cgit_print_view(const char *hex, char *path) +{ + unsigned char sha1[20]; + enum object_type type; + unsigned char *buf; + unsigned long size; + + if (get_sha1_hex(hex, sha1)){ + cgit_print_error(fmt("Bad hex value: %s", hex)); + return; + } + + type = sha1_object_info(sha1, &size); + if (type == OBJ_BAD) { + cgit_print_error(fmt("Bad object name: %s", hex)); + return; + } + + buf = read_sha1_file(sha1, &type, &size); + if (!buf) { + cgit_print_error(fmt("Error reading object %s", hex)); + return; + } + + buf[size] = '\0'; + html("<table class='list'>\n"); + html("<tr class='nohover'><th class='left'>"); + if (path) + htmlf("%s (", path); + htmlf("%s %s, %li bytes", typename(type), hex, size); + if (path) + html(")"); + + html(" <a href='"); + html_attr(cgit_pageurl(cgit_query_repo, "blob", + fmt("id=%s&path=%s", + hex, + path))); + html("'>download</a>"); + html("</th></tr>\n"); + html("<tr><td class='blob'>\n"); + html_txt(buf); + html("\n</td></tr>\n"); + html("</table>\n"); +} |