summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.h3
-rw-r--r--ui-log.c6
-rw-r--r--ui-repolist.c3
-rw-r--r--ui-shared.c13
-rw-r--r--ui-summary.c2
-rw-r--r--ui-tree.c2
6 files changed, 21 insertions, 8 deletions
diff --git a/cgit.h b/cgit.h
index 42036c3..163f355 100644
--- a/cgit.h
+++ b/cgit.h
@@ -193,90 +193,91 @@ extern void *cgit_free_commitinfo(struct commitinfo *info);
193extern int cgit_diff_files(const unsigned char *old_sha1, 193extern int cgit_diff_files(const unsigned char *old_sha1,
194 const unsigned char *new_sha1, 194 const unsigned char *new_sha1,
195 linediff_fn fn); 195 linediff_fn fn);
196 196
197extern void cgit_diff_tree(const unsigned char *old_sha1, 197extern void cgit_diff_tree(const unsigned char *old_sha1,
198 const unsigned char *new_sha1, 198 const unsigned char *new_sha1,
199 filepair_fn fn, const char *prefix); 199 filepair_fn fn, const char *prefix);
200 200
201extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); 201extern void cgit_diff_commit(struct commit *commit, filepair_fn fn);
202 202
203extern char *fmt(const char *format,...); 203extern char *fmt(const char *format,...);
204 204
205extern void html(const char *txt); 205extern void html(const char *txt);
206extern void htmlf(const char *format,...); 206extern void htmlf(const char *format,...);
207extern void html_txt(char *txt); 207extern void html_txt(char *txt);
208extern void html_ntxt(int len, char *txt); 208extern void html_ntxt(int len, char *txt);
209extern void html_attr(char *txt); 209extern void html_attr(char *txt);
210extern void html_hidden(char *name, char *value); 210extern void html_hidden(char *name, char *value);
211extern void html_option(char *value, char *text, char *selected_value); 211extern void html_option(char *value, char *text, char *selected_value);
212extern void html_link_open(char *url, char *title, char *class); 212extern void html_link_open(char *url, char *title, char *class);
213extern void html_link_close(void); 213extern void html_link_close(void);
214extern void html_filemode(unsigned short mode); 214extern void html_filemode(unsigned short mode);
215extern int html_include(const char *filename); 215extern int html_include(const char *filename);
216 216
217extern int cgit_read_config(const char *filename, configfn fn); 217extern int cgit_read_config(const char *filename, configfn fn);
218extern int cgit_parse_query(char *txt, configfn fn); 218extern int cgit_parse_query(char *txt, configfn fn);
219extern struct commitinfo *cgit_parse_commit(struct commit *commit); 219extern struct commitinfo *cgit_parse_commit(struct commit *commit);
220extern struct taginfo *cgit_parse_tag(struct tag *tag); 220extern struct taginfo *cgit_parse_tag(struct tag *tag);
221extern void cgit_parse_url(const char *url); 221extern void cgit_parse_url(const char *url);
222 222
223extern char *cache_safe_filename(const char *unsafe); 223extern char *cache_safe_filename(const char *unsafe);
224extern int cache_lock(struct cacheitem *item); 224extern int cache_lock(struct cacheitem *item);
225extern int cache_unlock(struct cacheitem *item); 225extern int cache_unlock(struct cacheitem *item);
226extern int cache_cancel_lock(struct cacheitem *item); 226extern int cache_cancel_lock(struct cacheitem *item);
227extern int cache_exist(struct cacheitem *item); 227extern int cache_exist(struct cacheitem *item);
228extern int cache_expired(struct cacheitem *item); 228extern int cache_expired(struct cacheitem *item);
229 229
230extern char *cgit_repourl(const char *reponame); 230extern char *cgit_repourl(const char *reponame);
231extern char *cgit_fileurl(const char *reponame, const char *pagename, 231extern char *cgit_fileurl(const char *reponame, const char *pagename,
232 const char *filename, const char *query); 232 const char *filename, const char *query);
233extern char *cgit_pageurl(const char *reponame, const char *pagename, 233extern char *cgit_pageurl(const char *reponame, const char *pagename,
234 const char *query); 234 const char *query);
235 235
236extern const char *cgit_repobasename(const char *reponame); 236extern const char *cgit_repobasename(const char *reponame);
237 237
238extern void cgit_tree_link(char *name, char *title, char *class, char *head, 238extern void cgit_tree_link(char *name, char *title, char *class, char *head,
239 char *rev, char *path); 239 char *rev, char *path);
240extern void cgit_log_link(char *name, char *title, char *class, char *head, 240extern void cgit_log_link(char *name, char *title, char *class, char *head,
241 char *rev, char *path, int ofs); 241 char *rev, char *path, int ofs, char *grep,
242 char *pattern);
242extern void cgit_commit_link(char *name, char *title, char *class, char *head, 243extern void cgit_commit_link(char *name, char *title, char *class, char *head,
243 char *rev); 244 char *rev);
244extern void cgit_refs_link(char *name, char *title, char *class, char *head, 245extern void cgit_refs_link(char *name, char *title, char *class, char *head,
245 char *rev, char *path); 246 char *rev, char *path);
246extern void cgit_snapshot_link(char *name, char *title, char *class, 247extern void cgit_snapshot_link(char *name, char *title, char *class,
247 char *head, char *rev, char *archivename); 248 char *head, char *rev, char *archivename);
248extern void cgit_diff_link(char *name, char *title, char *class, char *head, 249extern void cgit_diff_link(char *name, char *title, char *class, char *head,
249 char *new_rev, char *old_rev, char *path); 250 char *new_rev, char *old_rev, char *path);
250 251
251extern void cgit_object_link(struct object *obj); 252extern void cgit_object_link(struct object *obj);
252 253
253extern void cgit_print_error(char *msg); 254extern void cgit_print_error(char *msg);
254extern void cgit_print_date(time_t secs, char *format); 255extern void cgit_print_date(time_t secs, char *format);
255extern void cgit_print_age(time_t t, time_t max_relative, char *format); 256extern void cgit_print_age(time_t t, time_t max_relative, char *format);
256extern void cgit_print_docstart(char *title, struct cacheitem *item); 257extern void cgit_print_docstart(char *title, struct cacheitem *item);
257extern void cgit_print_docend(); 258extern void cgit_print_docend();
258extern void cgit_print_pageheader(char *title, int show_search); 259extern void cgit_print_pageheader(char *title, int show_search);
259extern void cgit_print_snapshot_start(const char *mimetype, 260extern void cgit_print_snapshot_start(const char *mimetype,
260 const char *filename, 261 const char *filename,
261 struct cacheitem *item); 262 struct cacheitem *item);
262extern void cgit_print_branches(int maxcount); 263extern void cgit_print_branches(int maxcount);
263extern void cgit_print_tags(int maxcount); 264extern void cgit_print_tags(int maxcount);
264 265
265extern void cgit_print_repolist(struct cacheitem *item); 266extern void cgit_print_repolist(struct cacheitem *item);
266extern void cgit_print_summary(); 267extern void cgit_print_summary();
267extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, 268extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep,
268 char *pattern, char *path, int pager); 269 char *pattern, char *path, int pager);
269extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); 270extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path);
270extern void cgit_print_tree(const char *rev, char *path); 271extern void cgit_print_tree(const char *rev, char *path);
271extern void cgit_print_commit(char *hex); 272extern void cgit_print_commit(char *hex);
272extern void cgit_print_refs(); 273extern void cgit_print_refs();
273extern void cgit_print_tag(char *revname); 274extern void cgit_print_tag(char *revname);
274extern void cgit_print_diff(const char *new_hex, const char *old_hex, const char *prefix); 275extern void cgit_print_diff(const char *new_hex, const char *old_hex, const char *prefix);
275extern void cgit_print_snapshot(struct cacheitem *item, const char *head, 276extern void cgit_print_snapshot(struct cacheitem *item, const char *head,
276 const char *hex, const char *prefix, 277 const char *hex, const char *prefix,
277 const char *filename, int snapshot); 278 const char *filename, int snapshot);
278extern void cgit_print_snapshot_links(const char *repo, const char *head, 279extern void cgit_print_snapshot_links(const char *repo, const char *head,
279 const char *hex, int snapshots); 280 const char *hex, int snapshots);
280extern int cgit_parse_snapshots_mask(const char *str); 281extern int cgit_parse_snapshots_mask(const char *str);
281 282
282#endif /* CGIT_H */ 283#endif /* CGIT_H */
diff --git a/ui-log.c b/ui-log.c
index e7f7d6f..9f5fdf6 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -73,59 +73,61 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
73 } 73 }
74 init_revisions(&rev, NULL); 74 init_revisions(&rev, NULL);
75 rev.abbrev = DEFAULT_ABBREV; 75 rev.abbrev = DEFAULT_ABBREV;
76 rev.commit_format = CMIT_FMT_DEFAULT; 76 rev.commit_format = CMIT_FMT_DEFAULT;
77 rev.verbose_header = 1; 77 rev.verbose_header = 1;
78 rev.show_root_diff = 0; 78 rev.show_root_diff = 0;
79 setup_revisions(argc, argv, &rev, NULL); 79 setup_revisions(argc, argv, &rev, NULL);
80 if (rev.grep_filter) { 80 if (rev.grep_filter) {
81 rev.grep_filter->regflags |= REG_ICASE; 81 rev.grep_filter->regflags |= REG_ICASE;
82 compile_grep_patterns(rev.grep_filter); 82 compile_grep_patterns(rev.grep_filter);
83 } 83 }
84 prepare_revision_walk(&rev); 84 prepare_revision_walk(&rev);
85 85
86 html("<table class='list nowrap'>"); 86 html("<table class='list nowrap'>");
87 html("<tr class='nohover'><th class='left'>Age</th>" 87 html("<tr class='nohover'><th class='left'>Age</th>"
88 "<th class='left'>Message</th>"); 88 "<th class='left'>Message</th>");
89 89
90 if (cgit_repo->enable_log_filecount) { 90 if (cgit_repo->enable_log_filecount) {
91 html("<th class='left'>Files</th>"); 91 html("<th class='left'>Files</th>");
92 if (cgit_repo->enable_log_linecount) 92 if (cgit_repo->enable_log_linecount)
93 html("<th class='left'>Lines</th>"); 93 html("<th class='left'>Lines</th>");
94 } 94 }
95 html("<th class='left'>Author</th></tr>\n"); 95 html("<th class='left'>Author</th></tr>\n");
96 96
97 if (ofs<0) 97 if (ofs<0)
98 ofs = 0; 98 ofs = 0;
99 99
100 for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) { 100 for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) {
101 free(commit->buffer); 101 free(commit->buffer);
102 commit->buffer = NULL; 102 commit->buffer = NULL;
103 free_commit_list(commit->parents); 103 free_commit_list(commit->parents);
104 commit->parents = NULL; 104 commit->parents = NULL;
105 } 105 }
106 106
107 for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) { 107 for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) {
108 print_commit(commit); 108 print_commit(commit);
109 free(commit->buffer); 109 free(commit->buffer);
110 commit->buffer = NULL; 110 commit->buffer = NULL;
111 free_commit_list(commit->parents); 111 free_commit_list(commit->parents);
112 commit->parents = NULL; 112 commit->parents = NULL;
113 } 113 }
114 html("</table>\n"); 114 html("</table>\n");
115 115
116 if (pager) { 116 if (pager) {
117 html("<div class='pager'>"); 117 html("<div class='pager'>");
118 if (ofs > 0) { 118 if (ofs > 0) {
119 cgit_log_link("[prev]", NULL, NULL, cgit_query_head, 119 cgit_log_link("[prev]", NULL, NULL, cgit_query_head,
120 cgit_query_sha1, cgit_query_path, 120 cgit_query_sha1, cgit_query_path,
121 ofs - cnt); 121 ofs - cnt, cgit_query_grep,
122 cgit_query_search);
122 html("&nbsp;"); 123 html("&nbsp;");
123 } 124 }
124 if ((commit = get_revision(&rev)) != NULL) { 125 if ((commit = get_revision(&rev)) != NULL) {
125 cgit_log_link("[next]", NULL, NULL, cgit_query_head, 126 cgit_log_link("[next]", NULL, NULL, cgit_query_head,
126 cgit_query_sha1, cgit_query_path, 127 cgit_query_sha1, cgit_query_path,
127 ofs + cnt); 128 ofs + cnt, cgit_query_grep,
129 cgit_query_search);
128 } 130 }
129 html("</div>"); 131 html("</div>");
130 } 132 }
131} 133}
diff --git a/ui-repolist.c b/ui-repolist.c
index 4c86543..9aa5c1e 100644
--- a/ui-repolist.c
+++ b/ui-repolist.c
@@ -53,57 +53,58 @@ void cgit_print_repolist(struct cacheitem *item)
53 cgit_print_docstart(cgit_root_title, item); 53 cgit_print_docstart(cgit_root_title, item);
54 cgit_print_pageheader(cgit_root_title, 0); 54 cgit_print_pageheader(cgit_root_title, 0);
55 55
56 html("<table class='list nowrap'>"); 56 html("<table class='list nowrap'>");
57 if (cgit_index_header) { 57 if (cgit_index_header) {
58 htmlf("<tr class='nohover'><td colspan='%d' class='include-block'>", 58 htmlf("<tr class='nohover'><td colspan='%d' class='include-block'>",
59 columns); 59 columns);
60 html_include(cgit_index_header); 60 html_include(cgit_index_header);
61 html("</td></tr>"); 61 html("</td></tr>");
62 } 62 }
63 html("<tr class='nohover'>" 63 html("<tr class='nohover'>"
64 "<th class='left'>Name</th>" 64 "<th class='left'>Name</th>"
65 "<th class='left'>Description</th>" 65 "<th class='left'>Description</th>"
66 "<th class='left'>Owner</th>" 66 "<th class='left'>Owner</th>"
67 "<th class='left'>Idle</th>"); 67 "<th class='left'>Idle</th>");
68 if (cgit_enable_index_links) 68 if (cgit_enable_index_links)
69 html("<th>Links</th>"); 69 html("<th>Links</th>");
70 html("</tr>\n"); 70 html("</tr>\n");
71 71
72 for (i=0; i<cgit_repolist.count; i++) { 72 for (i=0; i<cgit_repolist.count; i++) {
73 cgit_repo = &cgit_repolist.repos[i]; 73 cgit_repo = &cgit_repolist.repos[i];
74 if ((last_group == NULL && cgit_repo->group != NULL) || 74 if ((last_group == NULL && cgit_repo->group != NULL) ||
75 (last_group != NULL && cgit_repo->group == NULL) || 75 (last_group != NULL && cgit_repo->group == NULL) ||
76 (last_group != NULL && cgit_repo->group != NULL && 76 (last_group != NULL && cgit_repo->group != NULL &&
77 strcmp(cgit_repo->group, last_group))) { 77 strcmp(cgit_repo->group, last_group))) {
78 htmlf("<tr class='nohover'><td colspan='%d' class='repogroup'>", 78 htmlf("<tr class='nohover'><td colspan='%d' class='repogroup'>",
79 columns); 79 columns);
80 html_txt(cgit_repo->group); 80 html_txt(cgit_repo->group);
81 html("</td></tr>"); 81 html("</td></tr>");
82 last_group = cgit_repo->group; 82 last_group = cgit_repo->group;
83 } 83 }
84 htmlf("<tr><td class='%s'>", 84 htmlf("<tr><td class='%s'>",
85 cgit_repo->group ? "sublevel-repo" : "toplevel-repo"); 85 cgit_repo->group ? "sublevel-repo" : "toplevel-repo");
86 html_link_open(cgit_repourl(cgit_repo->url), NULL, NULL); 86 html_link_open(cgit_repourl(cgit_repo->url), NULL, NULL);
87 html_txt(cgit_repo->name); 87 html_txt(cgit_repo->name);
88 html_link_close(); 88 html_link_close();
89 html("</td><td>"); 89 html("</td><td>");
90 html_ntxt(cgit_max_repodesc_len, cgit_repo->desc); 90 html_ntxt(cgit_max_repodesc_len, cgit_repo->desc);
91 html("</td><td>"); 91 html("</td><td>");
92 html_txt(cgit_repo->owner); 92 html_txt(cgit_repo->owner);
93 html("</td><td>"); 93 html("</td><td>");
94 print_modtime(cgit_repo); 94 print_modtime(cgit_repo);
95 html("</td>"); 95 html("</td>");
96 if (cgit_enable_index_links) { 96 if (cgit_enable_index_links) {
97 html("<td>"); 97 html("<td>");
98 html_link_open(cgit_repourl(cgit_repo->url), 98 html_link_open(cgit_repourl(cgit_repo->url),
99 NULL, "button"); 99 NULL, "button");
100 html("summary</a>"); 100 html("summary</a>");
101 cgit_log_link("log", NULL, "button", NULL, NULL, NULL, 0); 101 cgit_log_link("log", NULL, "button", NULL, NULL, NULL,
102 0, NULL, NULL);
102 cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL); 103 cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL);
103 html("</td>"); 104 html("</td>");
104 } 105 }
105 html("</tr>\n"); 106 html("</tr>\n");
106 } 107 }
107 html("</table>"); 108 html("</table>");
108 cgit_print_docend(); 109 cgit_print_docend();
109} 110}
diff --git a/ui-shared.c b/ui-shared.c
index 1d66940..a03661a 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -149,107 +149,116 @@ static char *repolink(char *title, char *class, char *page, char *head,
149 html_attr(path); 149 html_attr(path);
150 } 150 }
151 } else { 151 } else {
152 html(cgit_script_name); 152 html(cgit_script_name);
153 html("?url="); 153 html("?url=");
154 html_attr(cgit_repo->url); 154 html_attr(cgit_repo->url);
155 if (cgit_repo->url[strlen(cgit_repo->url) - 1] != '/') 155 if (cgit_repo->url[strlen(cgit_repo->url) - 1] != '/')
156 html("/"); 156 html("/");
157 if (page) { 157 if (page) {
158 html(page); 158 html(page);
159 html("/"); 159 html("/");
160 if (path) 160 if (path)
161 html_attr(path); 161 html_attr(path);
162 } 162 }
163 delim = "&amp;"; 163 delim = "&amp;";
164 } 164 }
165 if (head && strcmp(head, cgit_repo->defbranch)) { 165 if (head && strcmp(head, cgit_repo->defbranch)) {
166 html(delim); 166 html(delim);
167 html("h="); 167 html("h=");
168 html_attr(head); 168 html_attr(head);
169 delim = "&amp;"; 169 delim = "&amp;";
170 } 170 }
171 return fmt("%s", delim); 171 return fmt("%s", delim);
172} 172}
173 173
174static void reporevlink(char *page, char *name, char *title, char *class, 174static void reporevlink(char *page, char *name, char *title, char *class,
175 char *head, char *rev, char *path) 175 char *head, char *rev, char *path)
176{ 176{
177 char *delim; 177 char *delim;
178 178
179 delim = repolink(title, class, page, head, path); 179 delim = repolink(title, class, page, head, path);
180 if (rev && strcmp(rev, cgit_query_head)) { 180 if (rev && strcmp(rev, cgit_query_head)) {
181 html(delim); 181 html(delim);
182 html("id="); 182 html("id=");
183 html_attr(rev); 183 html_attr(rev);
184 } 184 }
185 html("'>"); 185 html("'>");
186 html_txt(name); 186 html_txt(name);
187 html("</a>"); 187 html("</a>");
188} 188}
189 189
190void cgit_tree_link(char *name, char *title, char *class, char *head, 190void cgit_tree_link(char *name, char *title, char *class, char *head,
191 char *rev, char *path) 191 char *rev, char *path)
192{ 192{
193 reporevlink("tree", name, title, class, head, rev, path); 193 reporevlink("tree", name, title, class, head, rev, path);
194} 194}
195 195
196void cgit_log_link(char *name, char *title, char *class, char *head, 196void cgit_log_link(char *name, char *title, char *class, char *head,
197 char *rev, char *path, int ofs) 197 char *rev, char *path, int ofs, char *grep, char *pattern)
198{ 198{
199 char *delim; 199 char *delim;
200 200
201 delim = repolink(title, class, "log", head, path); 201 delim = repolink(title, class, "log", head, path);
202 if (rev && strcmp(rev, cgit_query_head)) { 202 if (rev && strcmp(rev, cgit_query_head)) {
203 html(delim); 203 html(delim);
204 html("id="); 204 html("id=");
205 html_attr(rev); 205 html_attr(rev);
206 delim = "&"; 206 delim = "&";
207 } 207 }
208 if (grep && pattern) {
209 html(delim);
210 html("qt=");
211 html_attr(grep);
212 delim = "&";
213 html(delim);
214 html("q=");
215 html_attr(pattern);
216 }
208 if (ofs > 0) { 217 if (ofs > 0) {
209 html(delim); 218 html(delim);
210 html("ofs="); 219 html("ofs=");
211 htmlf("%d", ofs); 220 htmlf("%d", ofs);
212 } 221 }
213 html("'>"); 222 html("'>");
214 html_txt(name); 223 html_txt(name);
215 html("</a>"); 224 html("</a>");
216} 225}
217 226
218void cgit_commit_link(char *name, char *title, char *class, char *head, 227void cgit_commit_link(char *name, char *title, char *class, char *head,
219 char *rev) 228 char *rev)
220{ 229{
221 if (strlen(name) > cgit_max_msg_len && cgit_max_msg_len >= 15) { 230 if (strlen(name) > cgit_max_msg_len && cgit_max_msg_len >= 15) {
222 name[cgit_max_msg_len] = '\0'; 231 name[cgit_max_msg_len] = '\0';
223 name[cgit_max_msg_len - 1] = '.'; 232 name[cgit_max_msg_len - 1] = '.';
224 name[cgit_max_msg_len - 2] = '.'; 233 name[cgit_max_msg_len - 2] = '.';
225 name[cgit_max_msg_len - 3] = '.'; 234 name[cgit_max_msg_len - 3] = '.';
226 } 235 }
227 reporevlink("commit", name, title, class, head, rev, NULL); 236 reporevlink("commit", name, title, class, head, rev, NULL);
228} 237}
229 238
230void cgit_refs_link(char *name, char *title, char *class, char *head, 239void cgit_refs_link(char *name, char *title, char *class, char *head,
231 char *rev, char *path) 240 char *rev, char *path)
232{ 241{
233 reporevlink("refs", name, title, class, head, rev, path); 242 reporevlink("refs", name, title, class, head, rev, path);
234} 243}
235 244
236void cgit_snapshot_link(char *name, char *title, char *class, char *head, 245void cgit_snapshot_link(char *name, char *title, char *class, char *head,
237 char *rev, char *archivename) 246 char *rev, char *archivename)
238{ 247{
239 reporevlink("snapshot", name, title, class, head, rev, archivename); 248 reporevlink("snapshot", name, title, class, head, rev, archivename);
240} 249}
241 250
242void cgit_diff_link(char *name, char *title, char *class, char *head, 251void cgit_diff_link(char *name, char *title, char *class, char *head,
243 char *new_rev, char *old_rev, char *path) 252 char *new_rev, char *old_rev, char *path)
244{ 253{
245 char *delim; 254 char *delim;
246 255
247 delim = repolink(title, class, "diff", head, path); 256 delim = repolink(title, class, "diff", head, path);
248 if (new_rev && strcmp(new_rev, cgit_query_head)) { 257 if (new_rev && strcmp(new_rev, cgit_query_head)) {
249 html(delim); 258 html(delim);
250 html("id="); 259 html("id=");
251 html_attr(new_rev); 260 html_attr(new_rev);
252 delim = "&amp;"; 261 delim = "&amp;";
253 } 262 }
254 if (old_rev) { 263 if (old_rev) {
255 html(delim); 264 html(delim);
@@ -416,97 +425,97 @@ void add_hidden_formfields(int incl_head, int incl_search)
416{ 425{
417 if (!cgit_virtual_root) { 426 if (!cgit_virtual_root) {
418 if (cgit_query_repo) 427 if (cgit_query_repo)
419 html_hidden("r", cgit_query_repo); 428 html_hidden("r", cgit_query_repo);
420 if (cgit_query_page) 429 if (cgit_query_page)
421 html_hidden("p", cgit_query_page); 430 html_hidden("p", cgit_query_page);
422 } 431 }
423 432
424 if (incl_head && strcmp(cgit_query_head, cgit_repo->defbranch)) 433 if (incl_head && strcmp(cgit_query_head, cgit_repo->defbranch))
425 html_hidden("h", cgit_query_head); 434 html_hidden("h", cgit_query_head);
426 435
427 if (cgit_query_sha1) 436 if (cgit_query_sha1)
428 html_hidden("id", cgit_query_sha1); 437 html_hidden("id", cgit_query_sha1);
429 if (cgit_query_sha2) 438 if (cgit_query_sha2)
430 html_hidden("id2", cgit_query_sha2); 439 html_hidden("id2", cgit_query_sha2);
431 440
432 if (incl_search) { 441 if (incl_search) {
433 if (cgit_query_grep) 442 if (cgit_query_grep)
434 html_hidden("qt", cgit_query_grep); 443 html_hidden("qt", cgit_query_grep);
435 if (cgit_query_search) 444 if (cgit_query_search)
436 html_hidden("q", cgit_query_search); 445 html_hidden("q", cgit_query_search);
437 } 446 }
438} 447}
439 448
440void cgit_print_pageheader(char *title, int show_search) 449void cgit_print_pageheader(char *title, int show_search)
441{ 450{
442 static const char *default_info = "This is cgit, a fast webinterface for git repositories"; 451 static const char *default_info = "This is cgit, a fast webinterface for git repositories";
443 int header = 0; 452 int header = 0;
444 453
445 html("<div id='sidebar'>\n"); 454 html("<div id='sidebar'>\n");
446 html("<a href='"); 455 html("<a href='");
447 html_attr(cgit_rooturl()); 456 html_attr(cgit_rooturl());
448 htmlf("'><div id='logo'><img src='%s' alt='cgit'/></div></a>\n", 457 htmlf("'><div id='logo'><img src='%s' alt='cgit'/></div></a>\n",
449 cgit_logo); 458 cgit_logo);
450 html("<div class='infobox'>"); 459 html("<div class='infobox'>");
451 if (cgit_query_repo) { 460 if (cgit_query_repo) {
452 html("<h1>"); 461 html("<h1>");
453 html_txt(strrpart(cgit_repo->name, 20)); 462 html_txt(strrpart(cgit_repo->name, 20));
454 html("</h1>\n"); 463 html("</h1>\n");
455 html_txt(cgit_repo->desc); 464 html_txt(cgit_repo->desc);
456 if (cgit_repo->owner) { 465 if (cgit_repo->owner) {
457 html("<p>\n<h1>owner</h1>\n"); 466 html("<p>\n<h1>owner</h1>\n");
458 html_txt(cgit_repo->owner); 467 html_txt(cgit_repo->owner);
459 } 468 }
460 html("<p>\n<h1>navigate</h1>\n"); 469 html("<p>\n<h1>navigate</h1>\n");
461 reporevlink(NULL, "summary", NULL, "menu", cgit_query_head, 470 reporevlink(NULL, "summary", NULL, "menu", cgit_query_head,
462 NULL, NULL); 471 NULL, NULL);
463 cgit_log_link("log", NULL, "menu", cgit_query_head, 472 cgit_log_link("log", NULL, "menu", cgit_query_head,
464 cgit_query_sha1, cgit_query_path, 0); 473 cgit_query_sha1, cgit_query_path, 0, NULL, NULL);
465 cgit_tree_link("tree", NULL, "menu", cgit_query_head, 474 cgit_tree_link("tree", NULL, "menu", cgit_query_head,
466 cgit_query_sha1, NULL); 475 cgit_query_sha1, NULL);
467 cgit_commit_link("commit", NULL, "menu", cgit_query_head, 476 cgit_commit_link("commit", NULL, "menu", cgit_query_head,
468 cgit_query_sha1); 477 cgit_query_sha1);
469 cgit_diff_link("diff", NULL, "menu", cgit_query_head, 478 cgit_diff_link("diff", NULL, "menu", cgit_query_head,
470 cgit_query_sha1, cgit_query_sha2, 479 cgit_query_sha1, cgit_query_sha2,
471 cgit_query_path); 480 cgit_query_path);
472 481
473 for_each_ref(print_archive_ref, &header); 482 for_each_ref(print_archive_ref, &header);
474 483
475 html("<p>\n<h1>branch</h1>\n"); 484 html("<p>\n<h1>branch</h1>\n");
476 html("<form method='get' action=''>\n"); 485 html("<form method='get' action=''>\n");
477 add_hidden_formfields(0, 1); 486 add_hidden_formfields(0, 1);
478 html("<select name='h' onchange='this.form.submit();'>\n"); 487 html("<select name='h' onchange='this.form.submit();'>\n");
479 for_each_branch_ref(print_branch_option, cgit_query_head); 488 for_each_branch_ref(print_branch_option, cgit_query_head);
480 html("</select>\n"); 489 html("</select>\n");
481 html("</form>\n"); 490 html("</form>\n");
482 491
483 html("<p>\n<h1>search</h1>\n"); 492 html("<p>\n<h1>search</h1>\n");
484 html("<form method='get' action='"); 493 html("<form method='get' action='");
485 html_attr(cgit_pageurl(cgit_query_repo, "log", NULL)); 494 html_attr(cgit_pageurl(cgit_query_repo, "log", NULL));
486 html("'>\n"); 495 html("'>\n");
487 add_hidden_formfields(1, 0); 496 add_hidden_formfields(1, 0);
488 html("<select name='qt'>\n"); 497 html("<select name='qt'>\n");
489 html_option("grep", "log msg", cgit_query_grep); 498 html_option("grep", "log msg", cgit_query_grep);
490 html_option("author", "author", cgit_query_grep); 499 html_option("author", "author", cgit_query_grep);
491 html_option("committer", "committer", cgit_query_grep); 500 html_option("committer", "committer", cgit_query_grep);
492 html("</select>\n"); 501 html("</select>\n");
493 html("<input class='txt' type='text' name='q' value='"); 502 html("<input class='txt' type='text' name='q' value='");
494 html_attr(cgit_query_search); 503 html_attr(cgit_query_search);
495 html("'/>\n"); 504 html("'/>\n");
496 html("</form>\n"); 505 html("</form>\n");
497 } else { 506 } else {
498 if (!cgit_index_info || html_include(cgit_index_info)) 507 if (!cgit_index_info || html_include(cgit_index_info))
499 html(default_info); 508 html(default_info);
500 } 509 }
501 510
502 html("</div>\n"); 511 html("</div>\n");
503 512
504 html("</div>\n<table class='grid'><tr><td id='content'>\n"); 513 html("</div>\n<table class='grid'><tr><td id='content'>\n");
505} 514}
506 515
507 516
508void cgit_print_snapshot_start(const char *mimetype, const char *filename, 517void cgit_print_snapshot_start(const char *mimetype, const char *filename,
509 struct cacheitem *item) 518 struct cacheitem *item)
510{ 519{
511 htmlf("Content-Type: %s\n", mimetype); 520 htmlf("Content-Type: %s\n", mimetype);
512 htmlf("Content-Disposition: inline; filename=\"%s\"\n", filename); 521 htmlf("Content-Disposition: inline; filename=\"%s\"\n", filename);
diff --git a/ui-summary.c b/ui-summary.c
index 39fe330..c856793 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -11,97 +11,97 @@
11static int header; 11static int header;
12 12
13static int cmp_age(int age1, int age2) 13static int cmp_age(int age1, int age2)
14{ 14{
15 if (age1 != 0 && age2 != 0) 15 if (age1 != 0 && age2 != 0)
16 return age2 - age1; 16 return age2 - age1;
17 17
18 if (age1 == 0 && age2 == 0) 18 if (age1 == 0 && age2 == 0)
19 return 0; 19 return 0;
20 20
21 if (age1 == 0) 21 if (age1 == 0)
22 return +1; 22 return +1;
23 23
24 return -1; 24 return -1;
25} 25}
26 26
27static int cmp_ref_name(const void *a, const void *b) 27static int cmp_ref_name(const void *a, const void *b)
28{ 28{
29 struct refinfo *r1 = *(struct refinfo **)a; 29 struct refinfo *r1 = *(struct refinfo **)a;
30 struct refinfo *r2 = *(struct refinfo **)b; 30 struct refinfo *r2 = *(struct refinfo **)b;
31 31
32 return strcmp(r1->refname, r2->refname); 32 return strcmp(r1->refname, r2->refname);
33} 33}
34 34
35static int cmp_branch_age(const void *a, const void *b) 35static int cmp_branch_age(const void *a, const void *b)
36{ 36{
37 struct refinfo *r1 = *(struct refinfo **)a; 37 struct refinfo *r1 = *(struct refinfo **)a;
38 struct refinfo *r2 = *(struct refinfo **)b; 38 struct refinfo *r2 = *(struct refinfo **)b;
39 39
40 return cmp_age(r1->commit->committer_date, r2->commit->committer_date); 40 return cmp_age(r1->commit->committer_date, r2->commit->committer_date);
41} 41}
42 42
43static int cmp_tag_age(const void *a, const void *b) 43static int cmp_tag_age(const void *a, const void *b)
44{ 44{
45 struct refinfo *r1 = *(struct refinfo **)a; 45 struct refinfo *r1 = *(struct refinfo **)a;
46 struct refinfo *r2 = *(struct refinfo **)b; 46 struct refinfo *r2 = *(struct refinfo **)b;
47 47
48 return cmp_age(r1->tag->tagger_date, r2->tag->tagger_date); 48 return cmp_age(r1->tag->tagger_date, r2->tag->tagger_date);
49} 49}
50 50
51static int print_branch(struct refinfo *ref) 51static int print_branch(struct refinfo *ref)
52{ 52{
53 struct commitinfo *info = ref->commit; 53 struct commitinfo *info = ref->commit;
54 char *name = (char *)ref->refname; 54 char *name = (char *)ref->refname;
55 55
56 if (!info) 56 if (!info)
57 return 1; 57 return 1;
58 html("<tr><td>"); 58 html("<tr><td>");
59 cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0); 59 cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0, NULL, NULL);
60 html("</td><td>"); 60 html("</td><td>");
61 61
62 if (ref->object->type == OBJ_COMMIT) { 62 if (ref->object->type == OBJ_COMMIT) {
63 cgit_print_age(info->commit->date, -1, NULL); 63 cgit_print_age(info->commit->date, -1, NULL);
64 html("</td><td>"); 64 html("</td><td>");
65 html_txt(info->author); 65 html_txt(info->author);
66 html("</td><td>"); 66 html("</td><td>");
67 cgit_commit_link(info->subject, NULL, NULL, name, NULL); 67 cgit_commit_link(info->subject, NULL, NULL, name, NULL);
68 } else { 68 } else {
69 html("</td><td></td><td>"); 69 html("</td><td></td><td>");
70 cgit_object_link(ref->object); 70 cgit_object_link(ref->object);
71 } 71 }
72 html("</td></tr>\n"); 72 html("</td></tr>\n");
73 return 0; 73 return 0;
74} 74}
75 75
76static void print_tag_header() 76static void print_tag_header()
77{ 77{
78 html("<tr class='nohover'><th class='left'>Tag</th>" 78 html("<tr class='nohover'><th class='left'>Tag</th>"
79 "<th class='left'>Age</th>" 79 "<th class='left'>Age</th>"
80 "<th class='left'>Author</th>" 80 "<th class='left'>Author</th>"
81 "<th class='left'>Reference</th></tr>\n"); 81 "<th class='left'>Reference</th></tr>\n");
82 header = 1; 82 header = 1;
83} 83}
84 84
85static int print_tag(struct refinfo *ref) 85static int print_tag(struct refinfo *ref)
86{ 86{
87 struct tag *tag; 87 struct tag *tag;
88 struct taginfo *info; 88 struct taginfo *info;
89 char *url, *name = (char *)ref->refname; 89 char *url, *name = (char *)ref->refname;
90 90
91 if (ref->object->type == OBJ_TAG) { 91 if (ref->object->type == OBJ_TAG) {
92 tag = (struct tag *)ref->object; 92 tag = (struct tag *)ref->object;
93 info = ref->tag; 93 info = ref->tag;
94 if (!tag || !info) 94 if (!tag || !info)
95 return 1; 95 return 1;
96 html("<tr><td>"); 96 html("<tr><td>");
97 url = cgit_pageurl(cgit_query_repo, "tag", 97 url = cgit_pageurl(cgit_query_repo, "tag",
98 fmt("id=%s", name)); 98 fmt("id=%s", name));
99 html_link_open(url, NULL, NULL); 99 html_link_open(url, NULL, NULL);
100 html_txt(name); 100 html_txt(name);
101 html_link_close(); 101 html_link_close();
102 html("</td><td>"); 102 html("</td><td>");
103 if (info->tagger_date > 0) 103 if (info->tagger_date > 0)
104 cgit_print_age(info->tagger_date, -1, NULL); 104 cgit_print_age(info->tagger_date, -1, NULL);
105 html("</td><td>"); 105 html("</td><td>");
106 if (info->tagger) 106 if (info->tagger)
107 html(info->tagger); 107 html(info->tagger);
diff --git a/ui-tree.c b/ui-tree.c
index d6bcec3..c22e30b 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -55,97 +55,97 @@ static void print_object(const unsigned char *sha1, char *path)
55 html_txt(buf + start); 55 html_txt(buf + start);
56 html("</td></tr>\n"); 56 html("</td></tr>\n");
57 html("</table>\n"); 57 html("</table>\n");
58} 58}
59 59
60 60
61static int ls_item(const unsigned char *sha1, const char *base, int baselen, 61static int ls_item(const unsigned char *sha1, const char *base, int baselen,
62 const char *pathname, unsigned int mode, int stage) 62 const char *pathname, unsigned int mode, int stage)
63{ 63{
64 char *name; 64 char *name;
65 char *fullpath; 65 char *fullpath;
66 enum object_type type; 66 enum object_type type;
67 unsigned long size = 0; 67 unsigned long size = 0;
68 68
69 name = xstrdup(pathname); 69 name = xstrdup(pathname);
70 fullpath = fmt("%s%s%s", cgit_query_path ? cgit_query_path : "", 70 fullpath = fmt("%s%s%s", cgit_query_path ? cgit_query_path : "",
71 cgit_query_path ? "/" : "", name); 71 cgit_query_path ? "/" : "", name);
72 72
73 type = sha1_object_info(sha1, &size); 73 type = sha1_object_info(sha1, &size);
74 if (type == OBJ_BAD && !S_ISGITLINK(mode)) { 74 if (type == OBJ_BAD && !S_ISGITLINK(mode)) {
75 htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>", 75 htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>",
76 name, 76 name,
77 sha1_to_hex(sha1)); 77 sha1_to_hex(sha1));
78 return 0; 78 return 0;
79 } 79 }
80 80
81 html("<tr><td class='ls-mode'>"); 81 html("<tr><td class='ls-mode'>");
82 html_filemode(mode); 82 html_filemode(mode);
83 html("</td><td>"); 83 html("</td><td>");
84 if (S_ISGITLINK(mode)) { 84 if (S_ISGITLINK(mode)) {
85 htmlf("<a class='ls-mod' href='"); 85 htmlf("<a class='ls-mod' href='");
86 html_attr(fmt(cgit_repo->module_link, 86 html_attr(fmt(cgit_repo->module_link,
87 name, 87 name,
88 sha1_to_hex(sha1))); 88 sha1_to_hex(sha1)));
89 html("'>"); 89 html("'>");
90 html_txt(name); 90 html_txt(name);
91 html("</a>"); 91 html("</a>");
92 } else if (S_ISDIR(mode)) { 92 } else if (S_ISDIR(mode)) {
93 cgit_tree_link(name, NULL, "ls-dir", cgit_query_head, 93 cgit_tree_link(name, NULL, "ls-dir", cgit_query_head,
94 curr_rev, fullpath); 94 curr_rev, fullpath);
95 } else { 95 } else {
96 cgit_tree_link(name, NULL, "ls-blob", cgit_query_head, 96 cgit_tree_link(name, NULL, "ls-blob", cgit_query_head,
97 curr_rev, fullpath); 97 curr_rev, fullpath);
98 } 98 }
99 htmlf("</td><td class='ls-size'>%li</td>", size); 99 htmlf("</td><td class='ls-size'>%li</td>", size);
100 100
101 html("<td>"); 101 html("<td>");
102 cgit_log_link("log", NULL, "button", cgit_query_head, curr_rev, 102 cgit_log_link("log", NULL, "button", cgit_query_head, curr_rev,
103 fullpath, 0); 103 fullpath, 0, NULL, NULL);
104 html("</td></tr>\n"); 104 html("</td></tr>\n");
105 free(name); 105 free(name);
106 return 0; 106 return 0;
107} 107}
108 108
109static void ls_head() 109static void ls_head()
110{ 110{
111 html("<table class='list'>\n"); 111 html("<table class='list'>\n");
112 html("<tr class='nohover'>"); 112 html("<tr class='nohover'>");
113 html("<th class='left'>Mode</th>"); 113 html("<th class='left'>Mode</th>");
114 html("<th class='left'>Name</th>"); 114 html("<th class='left'>Name</th>");
115 html("<th class='right'>Size</th>"); 115 html("<th class='right'>Size</th>");
116 html("<th/>"); 116 html("<th/>");
117 html("</tr>\n"); 117 html("</tr>\n");
118 header = 1; 118 header = 1;
119} 119}
120 120
121static void ls_tail() 121static void ls_tail()
122{ 122{
123 if (!header) 123 if (!header)
124 return; 124 return;
125 html("</table>\n"); 125 html("</table>\n");
126 header = 0; 126 header = 0;
127} 127}
128 128
129static void ls_tree(const unsigned char *sha1, char *path) 129static void ls_tree(const unsigned char *sha1, char *path)
130{ 130{
131 struct tree *tree; 131 struct tree *tree;
132 132
133 tree = parse_tree_indirect(sha1); 133 tree = parse_tree_indirect(sha1);
134 if (!tree) { 134 if (!tree) {
135 cgit_print_error(fmt("Not a tree object: %s", 135 cgit_print_error(fmt("Not a tree object: %s",
136 sha1_to_hex(sha1))); 136 sha1_to_hex(sha1)));
137 return; 137 return;
138 } 138 }
139 139
140 ls_head(); 140 ls_head();
141 read_tree_recursive(tree, "", 0, 1, NULL, ls_item); 141 read_tree_recursive(tree, "", 0, 1, NULL, ls_item);
142 ls_tail(); 142 ls_tail();
143} 143}
144 144
145 145
146static int walk_tree(const unsigned char *sha1, const char *base, int baselen, 146static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
147 const char *pathname, unsigned mode, int stage) 147 const char *pathname, unsigned mode, int stage)
148{ 148{
149 static int state; 149 static int state;
150 static char buffer[PATH_MAX]; 150 static char buffer[PATH_MAX];
151 char *url; 151 char *url;