author | Johan Herland <johan@herland.net> | 2010-11-15 17:39:52 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2010-11-16 07:18:37 (UTC) |
commit | ad230267f8ecae6cb4f0da17d7a5f75ba38203e2 (patch) (unidiff) | |
tree | b25cb32e8caf932b031691a5c85b827b847261c5 | |
parent | 268b34af23cdcac87aed3300bfe6154cbc65753e (diff) | |
download | cgit-ad230267f8ecae6cb4f0da17d7a5f75ba38203e2.zip cgit-ad230267f8ecae6cb4f0da17d7a5f75ba38203e2.tar.gz cgit-ad230267f8ecae6cb4f0da17d7a5f75ba38203e2.tar.bz2 |
ui-log: Line-wrap long commit subjects when showmsg is enabled
When showmsg is disabled ui-log truncates long commit subjects. This is good.
However, the same is not desirable when showmsg is enabled, since you then
end up with a truncated commit subject followed by the rest of the commit
message below.
Instead, when showmsg is enabled (and we're using all this space to display
the entire commit message, anyway), line-wrap the commit subject instead of
truncating it.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r-- | cmd.c | 3 | ||||
-rw-r--r-- | ui-log.c | 35 | ||||
-rw-r--r-- | ui-log.h | 3 | ||||
-rw-r--r-- | ui-summary.c | 2 |
4 files changed, 35 insertions, 8 deletions
@@ -6,129 +6,130 @@ | |||
6 | * (see COPYING for full license text) | 6 | * (see COPYING for full license text) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include "cgit.h" | 9 | #include "cgit.h" |
10 | #include "cmd.h" | 10 | #include "cmd.h" |
11 | #include "cache.h" | 11 | #include "cache.h" |
12 | #include "ui-shared.h" | 12 | #include "ui-shared.h" |
13 | #include "ui-atom.h" | 13 | #include "ui-atom.h" |
14 | #include "ui-blob.h" | 14 | #include "ui-blob.h" |
15 | #include "ui-clone.h" | 15 | #include "ui-clone.h" |
16 | #include "ui-commit.h" | 16 | #include "ui-commit.h" |
17 | #include "ui-diff.h" | 17 | #include "ui-diff.h" |
18 | #include "ui-log.h" | 18 | #include "ui-log.h" |
19 | #include "ui-patch.h" | 19 | #include "ui-patch.h" |
20 | #include "ui-plain.h" | 20 | #include "ui-plain.h" |
21 | #include "ui-refs.h" | 21 | #include "ui-refs.h" |
22 | #include "ui-repolist.h" | 22 | #include "ui-repolist.h" |
23 | #include "ui-snapshot.h" | 23 | #include "ui-snapshot.h" |
24 | #include "ui-stats.h" | 24 | #include "ui-stats.h" |
25 | #include "ui-summary.h" | 25 | #include "ui-summary.h" |
26 | #include "ui-tag.h" | 26 | #include "ui-tag.h" |
27 | #include "ui-tree.h" | 27 | #include "ui-tree.h" |
28 | 28 | ||
29 | static void HEAD_fn(struct cgit_context *ctx) | 29 | static void HEAD_fn(struct cgit_context *ctx) |
30 | { | 30 | { |
31 | cgit_clone_head(ctx); | 31 | cgit_clone_head(ctx); |
32 | } | 32 | } |
33 | 33 | ||
34 | static void atom_fn(struct cgit_context *ctx) | 34 | static void atom_fn(struct cgit_context *ctx) |
35 | { | 35 | { |
36 | cgit_print_atom(ctx->qry.head, ctx->qry.path, ctx->cfg.max_atom_items); | 36 | cgit_print_atom(ctx->qry.head, ctx->qry.path, ctx->cfg.max_atom_items); |
37 | } | 37 | } |
38 | 38 | ||
39 | static void about_fn(struct cgit_context *ctx) | 39 | static void about_fn(struct cgit_context *ctx) |
40 | { | 40 | { |
41 | if (ctx->repo) | 41 | if (ctx->repo) |
42 | cgit_print_repo_readme(ctx->qry.path); | 42 | cgit_print_repo_readme(ctx->qry.path); |
43 | else | 43 | else |
44 | cgit_print_site_readme(); | 44 | cgit_print_site_readme(); |
45 | } | 45 | } |
46 | 46 | ||
47 | static void blob_fn(struct cgit_context *ctx) | 47 | static void blob_fn(struct cgit_context *ctx) |
48 | { | 48 | { |
49 | cgit_print_blob(ctx->qry.sha1, ctx->qry.path, ctx->qry.head); | 49 | cgit_print_blob(ctx->qry.sha1, ctx->qry.path, ctx->qry.head); |
50 | } | 50 | } |
51 | 51 | ||
52 | static void commit_fn(struct cgit_context *ctx) | 52 | static void commit_fn(struct cgit_context *ctx) |
53 | { | 53 | { |
54 | cgit_print_commit(ctx->qry.sha1, ctx->qry.path); | 54 | cgit_print_commit(ctx->qry.sha1, ctx->qry.path); |
55 | } | 55 | } |
56 | 56 | ||
57 | static void diff_fn(struct cgit_context *ctx) | 57 | static void diff_fn(struct cgit_context *ctx) |
58 | { | 58 | { |
59 | cgit_print_diff(ctx->qry.sha1, ctx->qry.sha2, ctx->qry.path); | 59 | cgit_print_diff(ctx->qry.sha1, ctx->qry.sha2, ctx->qry.path); |
60 | } | 60 | } |
61 | 61 | ||
62 | static void info_fn(struct cgit_context *ctx) | 62 | static void info_fn(struct cgit_context *ctx) |
63 | { | 63 | { |
64 | cgit_clone_info(ctx); | 64 | cgit_clone_info(ctx); |
65 | } | 65 | } |
66 | 66 | ||
67 | static void log_fn(struct cgit_context *ctx) | 67 | static void log_fn(struct cgit_context *ctx) |
68 | { | 68 | { |
69 | cgit_print_log(ctx->qry.sha1, ctx->qry.ofs, ctx->cfg.max_commit_count, | 69 | cgit_print_log(ctx->qry.sha1, ctx->qry.ofs, ctx->cfg.max_commit_count, |
70 | ctx->qry.grep, ctx->qry.search, ctx->qry.path, 1); | 70 | ctx->qry.grep, ctx->qry.search, ctx->qry.path, 1, |
71 | ctx->repo->enable_commit_graph); | ||
71 | } | 72 | } |
72 | 73 | ||
73 | static void ls_cache_fn(struct cgit_context *ctx) | 74 | static void ls_cache_fn(struct cgit_context *ctx) |
74 | { | 75 | { |
75 | ctx->page.mimetype = "text/plain"; | 76 | ctx->page.mimetype = "text/plain"; |
76 | ctx->page.filename = "ls-cache.txt"; | 77 | ctx->page.filename = "ls-cache.txt"; |
77 | cgit_print_http_headers(ctx); | 78 | cgit_print_http_headers(ctx); |
78 | cache_ls(ctx->cfg.cache_root); | 79 | cache_ls(ctx->cfg.cache_root); |
79 | } | 80 | } |
80 | 81 | ||
81 | static void objects_fn(struct cgit_context *ctx) | 82 | static void objects_fn(struct cgit_context *ctx) |
82 | { | 83 | { |
83 | cgit_clone_objects(ctx); | 84 | cgit_clone_objects(ctx); |
84 | } | 85 | } |
85 | 86 | ||
86 | static void repolist_fn(struct cgit_context *ctx) | 87 | static void repolist_fn(struct cgit_context *ctx) |
87 | { | 88 | { |
88 | cgit_print_repolist(); | 89 | cgit_print_repolist(); |
89 | } | 90 | } |
90 | 91 | ||
91 | static void patch_fn(struct cgit_context *ctx) | 92 | static void patch_fn(struct cgit_context *ctx) |
92 | { | 93 | { |
93 | cgit_print_patch(ctx->qry.sha1, ctx->qry.path); | 94 | cgit_print_patch(ctx->qry.sha1, ctx->qry.path); |
94 | } | 95 | } |
95 | 96 | ||
96 | static void plain_fn(struct cgit_context *ctx) | 97 | static void plain_fn(struct cgit_context *ctx) |
97 | { | 98 | { |
98 | cgit_print_plain(ctx); | 99 | cgit_print_plain(ctx); |
99 | } | 100 | } |
100 | 101 | ||
101 | static void refs_fn(struct cgit_context *ctx) | 102 | static void refs_fn(struct cgit_context *ctx) |
102 | { | 103 | { |
103 | cgit_print_refs(); | 104 | cgit_print_refs(); |
104 | } | 105 | } |
105 | 106 | ||
106 | static void snapshot_fn(struct cgit_context *ctx) | 107 | static void snapshot_fn(struct cgit_context *ctx) |
107 | { | 108 | { |
108 | cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1, ctx->qry.path, | 109 | cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1, ctx->qry.path, |
109 | ctx->repo->snapshots, ctx->qry.nohead); | 110 | ctx->repo->snapshots, ctx->qry.nohead); |
110 | } | 111 | } |
111 | 112 | ||
112 | static void stats_fn(struct cgit_context *ctx) | 113 | static void stats_fn(struct cgit_context *ctx) |
113 | { | 114 | { |
114 | cgit_show_stats(ctx); | 115 | cgit_show_stats(ctx); |
115 | } | 116 | } |
116 | 117 | ||
117 | static void summary_fn(struct cgit_context *ctx) | 118 | static void summary_fn(struct cgit_context *ctx) |
118 | { | 119 | { |
119 | cgit_print_summary(); | 120 | cgit_print_summary(); |
120 | } | 121 | } |
121 | 122 | ||
122 | static void tag_fn(struct cgit_context *ctx) | 123 | static void tag_fn(struct cgit_context *ctx) |
123 | { | 124 | { |
124 | cgit_print_tag(ctx->qry.sha1); | 125 | cgit_print_tag(ctx->qry.sha1); |
125 | } | 126 | } |
126 | 127 | ||
127 | static void tree_fn(struct cgit_context *ctx) | 128 | static void tree_fn(struct cgit_context *ctx) |
128 | { | 129 | { |
129 | cgit_print_tree(ctx->qry.sha1, ctx->qry.path); | 130 | cgit_print_tree(ctx->qry.sha1, ctx->qry.path); |
130 | } | 131 | } |
131 | 132 | ||
132 | #define def_cmd(name, want_repo, want_layout, want_vpath) \ | 133 | #define def_cmd(name, want_repo, want_layout, want_vpath) \ |
133 | {#name, name##_fn, want_repo, want_layout, want_vpath} | 134 | {#name, name##_fn, want_repo, want_layout, want_vpath} |
134 | 135 | ||
@@ -37,349 +37,374 @@ void count_lines(char *line, int size) | |||
37 | add_lines++; | 37 | add_lines++; |
38 | 38 | ||
39 | else if (line[0] == '-') | 39 | else if (line[0] == '-') |
40 | rem_lines++; | 40 | rem_lines++; |
41 | } | 41 | } |
42 | 42 | ||
43 | void inspect_files(struct diff_filepair *pair) | 43 | void inspect_files(struct diff_filepair *pair) |
44 | { | 44 | { |
45 | unsigned long old_size = 0; | 45 | unsigned long old_size = 0; |
46 | unsigned long new_size = 0; | 46 | unsigned long new_size = 0; |
47 | int binary = 0; | 47 | int binary = 0; |
48 | 48 | ||
49 | files++; | 49 | files++; |
50 | if (ctx.repo->enable_log_linecount) | 50 | if (ctx.repo->enable_log_linecount) |
51 | cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, | 51 | cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, |
52 | &new_size, &binary, 0, ctx.qry.ignorews, | 52 | &new_size, &binary, 0, ctx.qry.ignorews, |
53 | count_lines); | 53 | count_lines); |
54 | } | 54 | } |
55 | 55 | ||
56 | void show_commit_decorations(struct commit *commit) | 56 | void show_commit_decorations(struct commit *commit) |
57 | { | 57 | { |
58 | struct name_decoration *deco; | 58 | struct name_decoration *deco; |
59 | static char buf[1024]; | 59 | static char buf[1024]; |
60 | 60 | ||
61 | buf[sizeof(buf) - 1] = 0; | 61 | buf[sizeof(buf) - 1] = 0; |
62 | deco = lookup_decoration(&name_decoration, &commit->object); | 62 | deco = lookup_decoration(&name_decoration, &commit->object); |
63 | while (deco) { | 63 | while (deco) { |
64 | if (!prefixcmp(deco->name, "refs/heads/")) { | 64 | if (!prefixcmp(deco->name, "refs/heads/")) { |
65 | strncpy(buf, deco->name + 11, sizeof(buf) - 1); | 65 | strncpy(buf, deco->name + 11, sizeof(buf) - 1); |
66 | cgit_log_link(buf, NULL, "branch-deco", buf, NULL, | 66 | cgit_log_link(buf, NULL, "branch-deco", buf, NULL, |
67 | ctx.qry.vpath, 0, NULL, NULL, | 67 | ctx.qry.vpath, 0, NULL, NULL, |
68 | ctx.qry.showmsg); | 68 | ctx.qry.showmsg); |
69 | } | 69 | } |
70 | else if (!prefixcmp(deco->name, "tag: refs/tags/")) { | 70 | else if (!prefixcmp(deco->name, "tag: refs/tags/")) { |
71 | strncpy(buf, deco->name + 15, sizeof(buf) - 1); | 71 | strncpy(buf, deco->name + 15, sizeof(buf) - 1); |
72 | cgit_tag_link(buf, NULL, "tag-deco", ctx.qry.head, buf); | 72 | cgit_tag_link(buf, NULL, "tag-deco", ctx.qry.head, buf); |
73 | } | 73 | } |
74 | else if (!prefixcmp(deco->name, "refs/tags/")) { | 74 | else if (!prefixcmp(deco->name, "refs/tags/")) { |
75 | strncpy(buf, deco->name + 10, sizeof(buf) - 1); | 75 | strncpy(buf, deco->name + 10, sizeof(buf) - 1); |
76 | cgit_tag_link(buf, NULL, "tag-deco", ctx.qry.head, buf); | 76 | cgit_tag_link(buf, NULL, "tag-deco", ctx.qry.head, buf); |
77 | } | 77 | } |
78 | else if (!prefixcmp(deco->name, "refs/remotes/")) { | 78 | else if (!prefixcmp(deco->name, "refs/remotes/")) { |
79 | strncpy(buf, deco->name + 13, sizeof(buf) - 1); | 79 | strncpy(buf, deco->name + 13, sizeof(buf) - 1); |
80 | cgit_log_link(buf, NULL, "remote-deco", NULL, | 80 | cgit_log_link(buf, NULL, "remote-deco", NULL, |
81 | sha1_to_hex(commit->object.sha1), | 81 | sha1_to_hex(commit->object.sha1), |
82 | ctx.qry.vpath, 0, NULL, NULL, | 82 | ctx.qry.vpath, 0, NULL, NULL, |
83 | ctx.qry.showmsg); | 83 | ctx.qry.showmsg); |
84 | } | 84 | } |
85 | else { | 85 | else { |
86 | strncpy(buf, deco->name, sizeof(buf) - 1); | 86 | strncpy(buf, deco->name, sizeof(buf) - 1); |
87 | cgit_commit_link(buf, NULL, "deco", ctx.qry.head, | 87 | cgit_commit_link(buf, NULL, "deco", ctx.qry.head, |
88 | sha1_to_hex(commit->object.sha1), | 88 | sha1_to_hex(commit->object.sha1), |
89 | ctx.qry.vpath, 0); | 89 | ctx.qry.vpath, 0); |
90 | } | 90 | } |
91 | deco = deco->next; | 91 | deco = deco->next; |
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
95 | void print_commit(struct commit *commit, struct rev_info *revs) | 95 | void print_commit(struct commit *commit, struct rev_info *revs) |
96 | { | 96 | { |
97 | struct commitinfo *info; | 97 | struct commitinfo *info; |
98 | char *tmp; | 98 | char *tmp; |
99 | int cols = 2; | 99 | int cols = 2; |
100 | struct strbuf graphbuf = STRBUF_INIT; | 100 | struct strbuf graphbuf = STRBUF_INIT; |
101 | struct strbuf msgbuf = STRBUF_INIT; | ||
101 | 102 | ||
102 | if (ctx.repo->enable_log_filecount) { | 103 | if (ctx.repo->enable_log_filecount) { |
103 | cols++; | 104 | cols++; |
104 | if (ctx.repo->enable_log_linecount) | 105 | if (ctx.repo->enable_log_linecount) |
105 | cols++; | 106 | cols++; |
106 | } | 107 | } |
107 | 108 | ||
108 | if (revs->graph) { | 109 | if (revs->graph) { |
109 | /* Advance graph until current commit */ | 110 | /* Advance graph until current commit */ |
110 | while (!graph_next_line(revs->graph, &graphbuf)) { | 111 | while (!graph_next_line(revs->graph, &graphbuf)) { |
111 | /* Print graph segment in otherwise empty table row */ | 112 | /* Print graph segment in otherwise empty table row */ |
112 | html("<tr class='nohover'><td/><td class='commitgraph'>"); | 113 | html("<tr class='nohover'><td/><td class='commitgraph'>"); |
113 | html(graphbuf.buf); | 114 | html(graphbuf.buf); |
114 | htmlf("</td><td colspan='%d' /></tr>\n", cols); | 115 | htmlf("</td><td colspan='%d' /></tr>\n", cols); |
115 | strbuf_setlen(&graphbuf, 0); | 116 | strbuf_setlen(&graphbuf, 0); |
116 | } | 117 | } |
117 | /* Current commit's graph segment is now ready in graphbuf */ | 118 | /* Current commit's graph segment is now ready in graphbuf */ |
118 | } | 119 | } |
119 | 120 | ||
120 | info = cgit_parse_commit(commit); | 121 | info = cgit_parse_commit(commit); |
121 | htmlf("<tr%s><td>", | 122 | htmlf("<tr%s><td>", |
122 | ctx.qry.showmsg ? " class='logheader'" : ""); | 123 | ctx.qry.showmsg ? " class='logheader'" : ""); |
123 | tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1)); | 124 | tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1)); |
124 | tmp = cgit_fileurl(ctx.repo->url, "commit", ctx.qry.vpath, tmp); | 125 | tmp = cgit_fileurl(ctx.repo->url, "commit", ctx.qry.vpath, tmp); |
125 | html_link_open(tmp, NULL, NULL); | 126 | html_link_open(tmp, NULL, NULL); |
126 | cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); | 127 | cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); |
127 | html_link_close(); | 128 | html_link_close(); |
128 | html("</td>"); | 129 | html("</td>"); |
129 | 130 | ||
130 | if (revs->graph) { | 131 | if (revs->graph) { |
131 | /* Print graph segment for current commit */ | 132 | /* Print graph segment for current commit */ |
132 | html("<td class='commitgraph'>"); | 133 | html("<td class='commitgraph'>"); |
133 | html(graphbuf.buf); | 134 | html(graphbuf.buf); |
134 | html("</td>"); | 135 | html("</td>"); |
135 | strbuf_setlen(&graphbuf, 0); | 136 | strbuf_setlen(&graphbuf, 0); |
136 | } | 137 | } |
137 | 138 | ||
138 | htmlf("<td%s>", ctx.qry.showmsg ? " class='logsubject'" : ""); | 139 | htmlf("<td%s>", ctx.qry.showmsg ? " class='logsubject'" : ""); |
140 | if (ctx.qry.showmsg) { | ||
141 | /* line-wrap long commit subjects instead of truncating them */ | ||
142 | size_t subject_len = strlen(info->subject); | ||
143 | |||
144 | if (subject_len > ctx.cfg.max_msg_len && | ||
145 | ctx.cfg.max_msg_len >= 15) { | ||
146 | /* symbol for signaling line-wrap (in PAGE_ENCODING) */ | ||
147 | const char wrap_symbol[] = { ' ', 0xE2, 0x86, 0xB5, 0 }; | ||
148 | int i = ctx.cfg.max_msg_len - strlen(wrap_symbol); | ||
149 | |||
150 | /* Rewind i to preceding space character */ | ||
151 | while (i > 0 && !isspace(info->subject[i])) | ||
152 | --i; | ||
153 | if (!i) /* Oops, zero spaces. Reset i */ | ||
154 | i = ctx.cfg.max_msg_len - strlen(wrap_symbol); | ||
155 | |||
156 | /* add remainder starting at i to msgbuf */ | ||
157 | strbuf_add(&msgbuf, info->subject + i, subject_len - i); | ||
158 | strbuf_trim(&msgbuf); | ||
159 | strbuf_add(&msgbuf, "\n\n", 2); | ||
160 | |||
161 | /* Place wrap_symbol at position i in info->subject */ | ||
162 | strcpy(info->subject + i, wrap_symbol); | ||
163 | } | ||
164 | } | ||
139 | cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, | 165 | cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, |
140 | sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0); | 166 | sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0); |
141 | show_commit_decorations(commit); | 167 | show_commit_decorations(commit); |
142 | html("</td><td>"); | 168 | html("</td><td>"); |
143 | html_txt(info->author); | 169 | html_txt(info->author); |
144 | if (ctx.repo->enable_log_filecount) { | 170 | if (ctx.repo->enable_log_filecount) { |
145 | files = 0; | 171 | files = 0; |
146 | add_lines = 0; | 172 | add_lines = 0; |
147 | rem_lines = 0; | 173 | rem_lines = 0; |
148 | cgit_diff_commit(commit, inspect_files, ctx.qry.vpath); | 174 | cgit_diff_commit(commit, inspect_files, ctx.qry.vpath); |
149 | html("</td><td>"); | 175 | html("</td><td>"); |
150 | htmlf("%d", files); | 176 | htmlf("%d", files); |
151 | if (ctx.repo->enable_log_linecount) { | 177 | if (ctx.repo->enable_log_linecount) { |
152 | html("</td><td>"); | 178 | html("</td><td>"); |
153 | htmlf("-%d/+%d", rem_lines, add_lines); | 179 | htmlf("-%d/+%d", rem_lines, add_lines); |
154 | } | 180 | } |
155 | } | 181 | } |
156 | html("</td></tr>\n"); | 182 | html("</td></tr>\n"); |
157 | 183 | ||
158 | if (revs->graph || ctx.qry.showmsg) { /* Print a second table row */ | 184 | if (revs->graph || ctx.qry.showmsg) { /* Print a second table row */ |
159 | struct strbuf msgbuf = STRBUF_INIT; | ||
160 | html("<tr class='nohover'><td/>"); /* Empty 'Age' column */ | 185 | html("<tr class='nohover'><td/>"); /* Empty 'Age' column */ |
161 | 186 | ||
162 | if (ctx.qry.showmsg) { | 187 | if (ctx.qry.showmsg) { |
163 | /* Concatenate commit message + notes in msgbuf */ | 188 | /* Concatenate commit message + notes in msgbuf */ |
164 | if (info->msg && *(info->msg)) { | 189 | if (info->msg && *(info->msg)) { |
165 | strbuf_addstr(&msgbuf, info->msg); | 190 | strbuf_addstr(&msgbuf, info->msg); |
166 | strbuf_addch(&msgbuf, '\n'); | 191 | strbuf_addch(&msgbuf, '\n'); |
167 | } | 192 | } |
168 | format_note(NULL, commit->object.sha1, &msgbuf, | 193 | format_note(NULL, commit->object.sha1, &msgbuf, |
169 | PAGE_ENCODING, | 194 | PAGE_ENCODING, |
170 | NOTES_SHOW_HEADER | NOTES_INDENT); | 195 | NOTES_SHOW_HEADER | NOTES_INDENT); |
171 | strbuf_addch(&msgbuf, '\n'); | 196 | strbuf_addch(&msgbuf, '\n'); |
172 | strbuf_ltrim(&msgbuf); | 197 | strbuf_ltrim(&msgbuf); |
173 | } | 198 | } |
174 | 199 | ||
175 | if (revs->graph) { | 200 | if (revs->graph) { |
176 | int lines = 0; | 201 | int lines = 0; |
177 | 202 | ||
178 | /* Calculate graph padding */ | 203 | /* Calculate graph padding */ |
179 | if (ctx.qry.showmsg) { | 204 | if (ctx.qry.showmsg) { |
180 | /* Count #lines in commit message + notes */ | 205 | /* Count #lines in commit message + notes */ |
181 | const char *p = msgbuf.buf; | 206 | const char *p = msgbuf.buf; |
182 | lines = 1; | 207 | lines = 1; |
183 | while ((p = strchr(p, '\n'))) { | 208 | while ((p = strchr(p, '\n'))) { |
184 | p++; | 209 | p++; |
185 | lines++; | 210 | lines++; |
186 | } | 211 | } |
187 | } | 212 | } |
188 | 213 | ||
189 | /* Print graph padding */ | 214 | /* Print graph padding */ |
190 | html("<td class='commitgraph'>"); | 215 | html("<td class='commitgraph'>"); |
191 | while (lines > 0 || !graph_is_commit_finished(revs->graph)) { | 216 | while (lines > 0 || !graph_is_commit_finished(revs->graph)) { |
192 | if (graphbuf.len) | 217 | if (graphbuf.len) |
193 | html("\n"); | 218 | html("\n"); |
194 | strbuf_setlen(&graphbuf, 0); | 219 | strbuf_setlen(&graphbuf, 0); |
195 | graph_next_line(revs->graph, &graphbuf); | 220 | graph_next_line(revs->graph, &graphbuf); |
196 | html(graphbuf.buf); | 221 | html(graphbuf.buf); |
197 | lines--; | 222 | lines--; |
198 | } | 223 | } |
199 | html("</td>\n"); | 224 | html("</td>\n"); |
200 | } | 225 | } |
201 | 226 | ||
202 | /* Print msgbuf into remainder of table row */ | 227 | /* Print msgbuf into remainder of table row */ |
203 | htmlf("<td colspan='%d'%s>\n", cols, | 228 | htmlf("<td colspan='%d'%s>\n", cols, |
204 | ctx.qry.showmsg ? " class='logmsg'" : ""); | 229 | ctx.qry.showmsg ? " class='logmsg'" : ""); |
205 | html_txt(msgbuf.buf); | 230 | html_txt(msgbuf.buf); |
206 | html("</td></tr>\n"); | 231 | html("</td></tr>\n"); |
207 | strbuf_release(&msgbuf); | ||
208 | } | 232 | } |
209 | 233 | ||
234 | strbuf_release(&msgbuf); | ||
210 | strbuf_release(&graphbuf); | 235 | strbuf_release(&graphbuf); |
211 | cgit_free_commitinfo(info); | 236 | cgit_free_commitinfo(info); |
212 | } | 237 | } |
213 | 238 | ||
214 | static const char *disambiguate_ref(const char *ref) | 239 | static const char *disambiguate_ref(const char *ref) |
215 | { | 240 | { |
216 | unsigned char sha1[20]; | 241 | unsigned char sha1[20]; |
217 | const char *longref; | 242 | const char *longref; |
218 | 243 | ||
219 | longref = fmt("refs/heads/%s", ref); | 244 | longref = fmt("refs/heads/%s", ref); |
220 | if (get_sha1(longref, sha1) == 0) | 245 | if (get_sha1(longref, sha1) == 0) |
221 | return longref; | 246 | return longref; |
222 | 247 | ||
223 | return ref; | 248 | return ref; |
224 | } | 249 | } |
225 | 250 | ||
226 | static char *next_token(char **src) | 251 | static char *next_token(char **src) |
227 | { | 252 | { |
228 | char *result; | 253 | char *result; |
229 | 254 | ||
230 | if (!src || !*src) | 255 | if (!src || !*src) |
231 | return NULL; | 256 | return NULL; |
232 | while (isspace(**src)) | 257 | while (isspace(**src)) |
233 | (*src)++; | 258 | (*src)++; |
234 | if (!**src) | 259 | if (!**src) |
235 | return NULL; | 260 | return NULL; |
236 | result = *src; | 261 | result = *src; |
237 | while (**src) { | 262 | while (**src) { |
238 | if (isspace(**src)) { | 263 | if (isspace(**src)) { |
239 | **src = '\0'; | 264 | **src = '\0'; |
240 | (*src)++; | 265 | (*src)++; |
241 | break; | 266 | break; |
242 | } | 267 | } |
243 | (*src)++; | 268 | (*src)++; |
244 | } | 269 | } |
245 | return result; | 270 | return result; |
246 | } | 271 | } |
247 | 272 | ||
248 | void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern, | 273 | void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern, |
249 | char *path, int pager) | 274 | char *path, int pager, int commit_graph) |
250 | { | 275 | { |
251 | struct rev_info rev; | 276 | struct rev_info rev; |
252 | struct commit *commit; | 277 | struct commit *commit; |
253 | struct vector vec = VECTOR_INIT(char *); | 278 | struct vector vec = VECTOR_INIT(char *); |
254 | int i, columns = 3; | 279 | int i, columns = 3; |
255 | char *arg; | 280 | char *arg; |
256 | 281 | ||
257 | /* First argv is NULL */ | 282 | /* First argv is NULL */ |
258 | vector_push(&vec, NULL, 0); | 283 | vector_push(&vec, NULL, 0); |
259 | 284 | ||
260 | if (!tip) | 285 | if (!tip) |
261 | tip = ctx.qry.head; | 286 | tip = ctx.qry.head; |
262 | tip = disambiguate_ref(tip); | 287 | tip = disambiguate_ref(tip); |
263 | vector_push(&vec, &tip, 0); | 288 | vector_push(&vec, &tip, 0); |
264 | 289 | ||
265 | if (grep && pattern && *pattern) { | 290 | if (grep && pattern && *pattern) { |
266 | pattern = xstrdup(pattern); | 291 | pattern = xstrdup(pattern); |
267 | if (!strcmp(grep, "grep") || !strcmp(grep, "author") || | 292 | if (!strcmp(grep, "grep") || !strcmp(grep, "author") || |
268 | !strcmp(grep, "committer")) { | 293 | !strcmp(grep, "committer")) { |
269 | arg = fmt("--%s=%s", grep, pattern); | 294 | arg = fmt("--%s=%s", grep, pattern); |
270 | vector_push(&vec, &arg, 0); | 295 | vector_push(&vec, &arg, 0); |
271 | } | 296 | } |
272 | if (!strcmp(grep, "range")) { | 297 | if (!strcmp(grep, "range")) { |
273 | /* Split the pattern at whitespace and add each token | 298 | /* Split the pattern at whitespace and add each token |
274 | * as a revision expression. Do not accept other | 299 | * as a revision expression. Do not accept other |
275 | * rev-list options. Also, replace the previously | 300 | * rev-list options. Also, replace the previously |
276 | * pushed tip (it's no longer relevant). | 301 | * pushed tip (it's no longer relevant). |
277 | */ | 302 | */ |
278 | vec.count--; | 303 | vec.count--; |
279 | while ((arg = next_token(&pattern))) { | 304 | while ((arg = next_token(&pattern))) { |
280 | if (*arg == '-') { | 305 | if (*arg == '-') { |
281 | fprintf(stderr, "Bad range expr: %s\n", | 306 | fprintf(stderr, "Bad range expr: %s\n", |
282 | arg); | 307 | arg); |
283 | break; | 308 | break; |
284 | } | 309 | } |
285 | vector_push(&vec, &arg, 0); | 310 | vector_push(&vec, &arg, 0); |
286 | } | 311 | } |
287 | } | 312 | } |
288 | } | 313 | } |
289 | if (ctx.repo->enable_commit_graph) { | 314 | if (commit_graph) { |
290 | static const char *graph_arg = "--graph"; | 315 | static const char *graph_arg = "--graph"; |
291 | static const char *color_arg = "--color"; | 316 | static const char *color_arg = "--color"; |
292 | vector_push(&vec, &graph_arg, 0); | 317 | vector_push(&vec, &graph_arg, 0); |
293 | vector_push(&vec, &color_arg, 0); | 318 | vector_push(&vec, &color_arg, 0); |
294 | graph_set_column_colors(column_colors_html, | 319 | graph_set_column_colors(column_colors_html, |
295 | COLUMN_COLORS_HTML_MAX); | 320 | COLUMN_COLORS_HTML_MAX); |
296 | } | 321 | } |
297 | 322 | ||
298 | if (path) { | 323 | if (path) { |
299 | arg = "--"; | 324 | arg = "--"; |
300 | vector_push(&vec, &arg, 0); | 325 | vector_push(&vec, &arg, 0); |
301 | vector_push(&vec, &path, 0); | 326 | vector_push(&vec, &path, 0); |
302 | } | 327 | } |
303 | 328 | ||
304 | /* Make sure the vector is NULL-terminated */ | 329 | /* Make sure the vector is NULL-terminated */ |
305 | vector_push(&vec, NULL, 0); | 330 | vector_push(&vec, NULL, 0); |
306 | vec.count--; | 331 | vec.count--; |
307 | 332 | ||
308 | init_revisions(&rev, NULL); | 333 | init_revisions(&rev, NULL); |
309 | rev.abbrev = DEFAULT_ABBREV; | 334 | rev.abbrev = DEFAULT_ABBREV; |
310 | rev.commit_format = CMIT_FMT_DEFAULT; | 335 | rev.commit_format = CMIT_FMT_DEFAULT; |
311 | rev.verbose_header = 1; | 336 | rev.verbose_header = 1; |
312 | rev.show_root_diff = 0; | 337 | rev.show_root_diff = 0; |
313 | setup_revisions(vec.count, vec.data, &rev, NULL); | 338 | setup_revisions(vec.count, vec.data, &rev, NULL); |
314 | load_ref_decorations(DECORATE_FULL_REFS); | 339 | load_ref_decorations(DECORATE_FULL_REFS); |
315 | rev.show_decorations = 1; | 340 | rev.show_decorations = 1; |
316 | rev.grep_filter.regflags |= REG_ICASE; | 341 | rev.grep_filter.regflags |= REG_ICASE; |
317 | compile_grep_patterns(&rev.grep_filter); | 342 | compile_grep_patterns(&rev.grep_filter); |
318 | prepare_revision_walk(&rev); | 343 | prepare_revision_walk(&rev); |
319 | 344 | ||
320 | if (pager) | 345 | if (pager) |
321 | html("<table class='list nowrap'>"); | 346 | html("<table class='list nowrap'>"); |
322 | 347 | ||
323 | html("<tr class='nohover'><th class='left'>Age</th>"); | 348 | html("<tr class='nohover'><th class='left'>Age</th>"); |
324 | if (ctx.repo->enable_commit_graph) | 349 | if (commit_graph) |
325 | html("<th></th>"); | 350 | html("<th></th>"); |
326 | html("<th class='left'>Commit message"); | 351 | html("<th class='left'>Commit message"); |
327 | if (pager) { | 352 | if (pager) { |
328 | html(" ("); | 353 | html(" ("); |
329 | cgit_log_link(ctx.qry.showmsg ? "Collapse" : "Expand", NULL, | 354 | cgit_log_link(ctx.qry.showmsg ? "Collapse" : "Expand", NULL, |
330 | NULL, ctx.qry.head, ctx.qry.sha1, | 355 | NULL, ctx.qry.head, ctx.qry.sha1, |
331 | ctx.qry.vpath, ctx.qry.ofs, ctx.qry.grep, | 356 | ctx.qry.vpath, ctx.qry.ofs, ctx.qry.grep, |
332 | ctx.qry.search, ctx.qry.showmsg ? 0 : 1); | 357 | ctx.qry.search, ctx.qry.showmsg ? 0 : 1); |
333 | html(")"); | 358 | html(")"); |
334 | } | 359 | } |
335 | html("</th><th class='left'>Author</th>"); | 360 | html("</th><th class='left'>Author</th>"); |
336 | if (ctx.repo->enable_log_filecount) { | 361 | if (ctx.repo->enable_log_filecount) { |
337 | html("<th class='left'>Files</th>"); | 362 | html("<th class='left'>Files</th>"); |
338 | columns++; | 363 | columns++; |
339 | if (ctx.repo->enable_log_linecount) { | 364 | if (ctx.repo->enable_log_linecount) { |
340 | html("<th class='left'>Lines</th>"); | 365 | html("<th class='left'>Lines</th>"); |
341 | columns++; | 366 | columns++; |
342 | } | 367 | } |
343 | } | 368 | } |
344 | html("</tr>\n"); | 369 | html("</tr>\n"); |
345 | 370 | ||
346 | if (ofs<0) | 371 | if (ofs<0) |
347 | ofs = 0; | 372 | ofs = 0; |
348 | 373 | ||
349 | for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) { | 374 | for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) { |
350 | free(commit->buffer); | 375 | free(commit->buffer); |
351 | commit->buffer = NULL; | 376 | commit->buffer = NULL; |
352 | free_commit_list(commit->parents); | 377 | free_commit_list(commit->parents); |
353 | commit->parents = NULL; | 378 | commit->parents = NULL; |
354 | } | 379 | } |
355 | 380 | ||
356 | for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) { | 381 | for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) { |
357 | print_commit(commit, &rev); | 382 | print_commit(commit, &rev); |
358 | free(commit->buffer); | 383 | free(commit->buffer); |
359 | commit->buffer = NULL; | 384 | commit->buffer = NULL; |
360 | free_commit_list(commit->parents); | 385 | free_commit_list(commit->parents); |
361 | commit->parents = NULL; | 386 | commit->parents = NULL; |
362 | } | 387 | } |
363 | if (pager) { | 388 | if (pager) { |
364 | html("</table><div class='pager'>"); | 389 | html("</table><div class='pager'>"); |
365 | if (ofs > 0) { | 390 | if (ofs > 0) { |
366 | cgit_log_link("[prev]", NULL, NULL, ctx.qry.head, | 391 | cgit_log_link("[prev]", NULL, NULL, ctx.qry.head, |
367 | ctx.qry.sha1, ctx.qry.vpath, | 392 | ctx.qry.sha1, ctx.qry.vpath, |
368 | ofs - cnt, ctx.qry.grep, | 393 | ofs - cnt, ctx.qry.grep, |
369 | ctx.qry.search, ctx.qry.showmsg); | 394 | ctx.qry.search, ctx.qry.showmsg); |
370 | html(" "); | 395 | html(" "); |
371 | } | 396 | } |
372 | if ((commit = get_revision(&rev)) != NULL) { | 397 | if ((commit = get_revision(&rev)) != NULL) { |
373 | cgit_log_link("[next]", NULL, NULL, ctx.qry.head, | 398 | cgit_log_link("[next]", NULL, NULL, ctx.qry.head, |
374 | ctx.qry.sha1, ctx.qry.vpath, | 399 | ctx.qry.sha1, ctx.qry.vpath, |
375 | ofs + cnt, ctx.qry.grep, | 400 | ofs + cnt, ctx.qry.grep, |
376 | ctx.qry.search, ctx.qry.showmsg); | 401 | ctx.qry.search, ctx.qry.showmsg); |
377 | } | 402 | } |
378 | html("</div>"); | 403 | html("</div>"); |
379 | } else if ((commit = get_revision(&rev)) != NULL) { | 404 | } else if ((commit = get_revision(&rev)) != NULL) { |
380 | html("<tr class='nohover'><td colspan='3'>"); | 405 | html("<tr class='nohover'><td colspan='3'>"); |
381 | cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL, | 406 | cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL, |
382 | ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg); | 407 | ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg); |
383 | html("</td></tr>\n"); | 408 | html("</td></tr>\n"); |
384 | } | 409 | } |
385 | } | 410 | } |
@@ -1,8 +1,9 @@ | |||
1 | #ifndef UI_LOG_H | 1 | #ifndef UI_LOG_H |
2 | #define UI_LOG_H | 2 | #define UI_LOG_H |
3 | 3 | ||
4 | extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, | 4 | extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, |
5 | char *pattern, char *path, int pager); | 5 | char *pattern, char *path, int pager, |
6 | int commit_graph); | ||
6 | extern void show_commit_decorations(struct commit *commit); | 7 | extern void show_commit_decorations(struct commit *commit); |
7 | 8 | ||
8 | #endif /* UI_LOG_H */ | 9 | #endif /* UI_LOG_H */ |
diff --git a/ui-summary.c b/ui-summary.c index b203bcc..5be2545 100644 --- a/ui-summary.c +++ b/ui-summary.c | |||
@@ -1,124 +1,124 @@ | |||
1 | /* ui-summary.c: functions for generating repo summary page | 1 | /* ui-summary.c: functions for generating repo summary page |
2 | * | 2 | * |
3 | * Copyright (C) 2006 Lars Hjemli | 3 | * Copyright (C) 2006 Lars Hjemli |
4 | * Copyright (C) 2010 Jason A. Donenfeld <Jason@zx2c4.com> | 4 | * Copyright (C) 2010 Jason A. Donenfeld <Jason@zx2c4.com> |
5 | * | 5 | * |
6 | * Licensed under GNU General Public License v2 | 6 | * Licensed under GNU General Public License v2 |
7 | * (see COPYING for full license text) | 7 | * (see COPYING for full license text) |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include "cgit.h" | 10 | #include "cgit.h" |
11 | #include "html.h" | 11 | #include "html.h" |
12 | #include "ui-log.h" | 12 | #include "ui-log.h" |
13 | #include "ui-refs.h" | 13 | #include "ui-refs.h" |
14 | #include "ui-blob.h" | 14 | #include "ui-blob.h" |
15 | 15 | ||
16 | int urls = 0; | 16 | int urls = 0; |
17 | 17 | ||
18 | static void print_url(char *base, char *suffix) | 18 | static void print_url(char *base, char *suffix) |
19 | { | 19 | { |
20 | if (!base || !*base) | 20 | if (!base || !*base) |
21 | return; | 21 | return; |
22 | if (urls++ == 0) { | 22 | if (urls++ == 0) { |
23 | html("<tr class='nohover'><td colspan='4'> </td></tr>"); | 23 | html("<tr class='nohover'><td colspan='4'> </td></tr>"); |
24 | html("<tr><th class='left' colspan='4'>Clone</th></tr>\n"); | 24 | html("<tr><th class='left' colspan='4'>Clone</th></tr>\n"); |
25 | } | 25 | } |
26 | if (suffix && *suffix) | 26 | if (suffix && *suffix) |
27 | base = fmt("%s/%s", base, suffix); | 27 | base = fmt("%s/%s", base, suffix); |
28 | html("<tr><td colspan='4'><a href='"); | 28 | html("<tr><td colspan='4'><a href='"); |
29 | html_url_path(base); | 29 | html_url_path(base); |
30 | html("'>"); | 30 | html("'>"); |
31 | html_txt(base); | 31 | html_txt(base); |
32 | html("</a></td></tr>\n"); | 32 | html("</a></td></tr>\n"); |
33 | } | 33 | } |
34 | 34 | ||
35 | static void print_urls(char *txt, char *suffix) | 35 | static void print_urls(char *txt, char *suffix) |
36 | { | 36 | { |
37 | char *h = txt, *t, c; | 37 | char *h = txt, *t, c; |
38 | 38 | ||
39 | while (h && *h) { | 39 | while (h && *h) { |
40 | while (h && *h == ' ') | 40 | while (h && *h == ' ') |
41 | h++; | 41 | h++; |
42 | t = h; | 42 | t = h; |
43 | while (t && *t && *t != ' ') | 43 | while (t && *t && *t != ' ') |
44 | t++; | 44 | t++; |
45 | c = *t; | 45 | c = *t; |
46 | *t = 0; | 46 | *t = 0; |
47 | print_url(h, suffix); | 47 | print_url(h, suffix); |
48 | *t = c; | 48 | *t = c; |
49 | h = t; | 49 | h = t; |
50 | } | 50 | } |
51 | } | 51 | } |
52 | 52 | ||
53 | void cgit_print_summary() | 53 | void cgit_print_summary() |
54 | { | 54 | { |
55 | html("<table summary='repository info' class='list nowrap'>"); | 55 | html("<table summary='repository info' class='list nowrap'>"); |
56 | cgit_print_branches(ctx.cfg.summary_branches); | 56 | cgit_print_branches(ctx.cfg.summary_branches); |
57 | html("<tr class='nohover'><td colspan='4'> </td></tr>"); | 57 | html("<tr class='nohover'><td colspan='4'> </td></tr>"); |
58 | cgit_print_tags(ctx.cfg.summary_tags); | 58 | cgit_print_tags(ctx.cfg.summary_tags); |
59 | if (ctx.cfg.summary_log > 0) { | 59 | if (ctx.cfg.summary_log > 0) { |
60 | html("<tr class='nohover'><td colspan='4'> </td></tr>"); | 60 | html("<tr class='nohover'><td colspan='4'> </td></tr>"); |
61 | cgit_print_log(ctx.qry.head, 0, ctx.cfg.summary_log, NULL, | 61 | cgit_print_log(ctx.qry.head, 0, ctx.cfg.summary_log, NULL, |
62 | NULL, NULL, 0); | 62 | NULL, NULL, 0, 0); |
63 | } | 63 | } |
64 | if (ctx.repo->clone_url) | 64 | if (ctx.repo->clone_url) |
65 | print_urls(ctx.repo->clone_url, NULL); | 65 | print_urls(ctx.repo->clone_url, NULL); |
66 | else if (ctx.cfg.clone_prefix) | 66 | else if (ctx.cfg.clone_prefix) |
67 | print_urls(ctx.cfg.clone_prefix, ctx.repo->url); | 67 | print_urls(ctx.cfg.clone_prefix, ctx.repo->url); |
68 | html("</table>"); | 68 | html("</table>"); |
69 | } | 69 | } |
70 | 70 | ||
71 | void cgit_print_repo_readme(char *path) | 71 | void cgit_print_repo_readme(char *path) |
72 | { | 72 | { |
73 | char *slash, *tmp, *colon, *ref; | 73 | char *slash, *tmp, *colon, *ref; |
74 | 74 | ||
75 | if (!ctx.repo->readme || !(*ctx.repo->readme)) | 75 | if (!ctx.repo->readme || !(*ctx.repo->readme)) |
76 | return; | 76 | return; |
77 | 77 | ||
78 | ref = NULL; | 78 | ref = NULL; |
79 | 79 | ||
80 | /* Check if the readme is tracked in the git repo. */ | 80 | /* Check if the readme is tracked in the git repo. */ |
81 | colon = strchr(ctx.repo->readme, ':'); | 81 | colon = strchr(ctx.repo->readme, ':'); |
82 | if (colon && strlen(colon) > 1) { | 82 | if (colon && strlen(colon) > 1) { |
83 | *colon = '\0'; | 83 | *colon = '\0'; |
84 | ref = ctx.repo->readme; | 84 | ref = ctx.repo->readme; |
85 | ctx.repo->readme = colon + 1; | 85 | ctx.repo->readme = colon + 1; |
86 | if (!(*ctx.repo->readme)) | 86 | if (!(*ctx.repo->readme)) |
87 | return; | 87 | return; |
88 | } | 88 | } |
89 | 89 | ||
90 | /* Prepend repo path to relative readme path unless tracked. */ | 90 | /* Prepend repo path to relative readme path unless tracked. */ |
91 | if (!ref && *ctx.repo->readme != '/') | 91 | if (!ref && *ctx.repo->readme != '/') |
92 | ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, | 92 | ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, |
93 | ctx.repo->readme)); | 93 | ctx.repo->readme)); |
94 | 94 | ||
95 | /* If a subpath is specified for the about page, make it relative | 95 | /* If a subpath is specified for the about page, make it relative |
96 | * to the directory containing the configured readme. | 96 | * to the directory containing the configured readme. |
97 | */ | 97 | */ |
98 | if (path) { | 98 | if (path) { |
99 | slash = strrchr(ctx.repo->readme, '/'); | 99 | slash = strrchr(ctx.repo->readme, '/'); |
100 | if (!slash) { | 100 | if (!slash) { |
101 | if (!colon) | 101 | if (!colon) |
102 | return; | 102 | return; |
103 | slash = colon; | 103 | slash = colon; |
104 | } | 104 | } |
105 | tmp = xmalloc(slash - ctx.repo->readme + 1 + strlen(path) + 1); | 105 | tmp = xmalloc(slash - ctx.repo->readme + 1 + strlen(path) + 1); |
106 | strncpy(tmp, ctx.repo->readme, slash - ctx.repo->readme + 1); | 106 | strncpy(tmp, ctx.repo->readme, slash - ctx.repo->readme + 1); |
107 | strcpy(tmp + (slash - ctx.repo->readme + 1), path); | 107 | strcpy(tmp + (slash - ctx.repo->readme + 1), path); |
108 | } else | 108 | } else |
109 | tmp = ctx.repo->readme; | 109 | tmp = ctx.repo->readme; |
110 | 110 | ||
111 | /* Print the calculated readme, either from the git repo or from the | 111 | /* Print the calculated readme, either from the git repo or from the |
112 | * filesystem, while applying the about-filter. | 112 | * filesystem, while applying the about-filter. |
113 | */ | 113 | */ |
114 | html("<div id='summary'>"); | 114 | html("<div id='summary'>"); |
115 | if (ctx.repo->about_filter) | 115 | if (ctx.repo->about_filter) |
116 | cgit_open_filter(ctx.repo->about_filter); | 116 | cgit_open_filter(ctx.repo->about_filter); |
117 | if (ref) | 117 | if (ref) |
118 | cgit_print_file(tmp, ref); | 118 | cgit_print_file(tmp, ref); |
119 | else | 119 | else |
120 | html_include(tmp); | 120 | html_include(tmp); |
121 | if (ctx.repo->about_filter) | 121 | if (ctx.repo->about_filter) |
122 | cgit_close_filter(ctx.repo->about_filter); | 122 | cgit_close_filter(ctx.repo->about_filter); |
123 | html("</div>"); | 123 | html("</div>"); |
124 | } | 124 | } |