summaryrefslogtreecommitdiffabout
path: root/ui-tree.c
authorLars Hjemli <hjemli@gmail.com>2009-08-21 12:26:52 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2009-08-21 12:26:52 (UTC)
commitb0f946bcc7f08168ea2858d8658a74a32accd7f5 (patch) (unidiff)
tree6bda2ca8e07bc19070155f5aa7e6e32e05d02782 /ui-tree.c
parentd67cc7f9d556650438e421cdcda37bc52710bffd (diff)
downloadcgit-b0f946bcc7f08168ea2858d8658a74a32accd7f5.zip
cgit-b0f946bcc7f08168ea2858d8658a74a32accd7f5.tar.gz
cgit-b0f946bcc7f08168ea2858d8658a74a32accd7f5.tar.bz2
Rename "linenumbers" to "enable-tree-linenumbers", change default to "1"
This makes the name of the cgitrc option more descriptive and at the same time changes the default from "0" to "1" in an attempt to stay backwards compatible - prior to the introduction of "source-filter" and "linenumbers", cgit always generated linenumber links in the tree view, but now this feature can be turned off (one might want to do this if the source-filter performs line-wrapping etc). While at it, the documentation is updated to match the surrounding descriptions. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'ui-tree.c') (more/less context) (ignore whitespace changes)
-rw-r--r--ui-tree.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/ui-tree.c b/ui-tree.c
index f64e6e0..f53ab64 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -1,285 +1,285 @@
1/* ui-tree.c: functions for tree output 1/* ui-tree.c: functions for tree output
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include <ctype.h> 9#include <ctype.h>
10#include "cgit.h" 10#include "cgit.h"
11#include "html.h" 11#include "html.h"
12#include "ui-shared.h" 12#include "ui-shared.h"
13 13
14char *curr_rev; 14char *curr_rev;
15char *match_path; 15char *match_path;
16int header = 0; 16int header = 0;
17 17
18static void print_text_buffer(const char *name, char *buf, unsigned long size) 18static void print_text_buffer(const char *name, char *buf, unsigned long size)
19{ 19{
20 unsigned long lineno, idx; 20 unsigned long lineno, idx;
21 const char *numberfmt = 21 const char *numberfmt =
22 "<a class='no' id='n%1$d' name='n%1$d' href='#n%1$d'>%1$d</a>\n"; 22 "<a class='no' id='n%1$d' name='n%1$d' href='#n%1$d'>%1$d</a>\n";
23 23
24 html("<table summary='blob content' class='blob'>\n"); 24 html("<table summary='blob content' class='blob'>\n");
25 25
26 if (ctx.cfg.linenumbers) { 26 if (ctx.cfg.enable_tree_linenumbers) {
27 html("<tr><td class='linenumbers'><pre>"); 27 html("<tr><td class='linenumbers'><pre>");
28 idx = 0; 28 idx = 0;
29 lineno = 0; 29 lineno = 0;
30 30
31 if (size) { 31 if (size) {
32 htmlf(numberfmt, ++lineno); 32 htmlf(numberfmt, ++lineno);
33 while(idx < size - 1) { // skip absolute last newline 33 while(idx < size - 1) { // skip absolute last newline
34 if (buf[idx] == '\n') 34 if (buf[idx] == '\n')
35 htmlf(numberfmt, ++lineno); 35 htmlf(numberfmt, ++lineno);
36 idx++; 36 idx++;
37 } 37 }
38 } 38 }
39 html("</pre></td>\n"); 39 html("</pre></td>\n");
40 } 40 }
41 else { 41 else {
42 html("<tr>\n"); 42 html("<tr>\n");
43 } 43 }
44 44
45 if (ctx.repo->source_filter) { 45 if (ctx.repo->source_filter) {
46 html("<td class='lines'><pre><code>"); 46 html("<td class='lines'><pre><code>");
47 ctx.repo->source_filter->argv[1] = xstrdup(name); 47 ctx.repo->source_filter->argv[1] = xstrdup(name);
48 cgit_open_filter(ctx.repo->source_filter); 48 cgit_open_filter(ctx.repo->source_filter);
49 write(STDOUT_FILENO, buf, size); 49 write(STDOUT_FILENO, buf, size);
50 cgit_close_filter(ctx.repo->source_filter); 50 cgit_close_filter(ctx.repo->source_filter);
51 html("</code></pre></td></tr></table>\n"); 51 html("</code></pre></td></tr></table>\n");
52 return; 52 return;
53 } 53 }
54 54
55 html("<td class='lines'><pre><code>"); 55 html("<td class='lines'><pre><code>");
56 html_txt(buf); 56 html_txt(buf);
57 html("</code></pre></td></tr></table>\n"); 57 html("</code></pre></td></tr></table>\n");
58} 58}
59 59
60#define ROWLEN 32 60#define ROWLEN 32
61 61
62static void print_binary_buffer(char *buf, unsigned long size) 62static void print_binary_buffer(char *buf, unsigned long size)
63{ 63{
64 unsigned long ofs, idx; 64 unsigned long ofs, idx;
65 static char ascii[ROWLEN + 1]; 65 static char ascii[ROWLEN + 1];
66 66
67 html("<table summary='blob content' class='bin-blob'>\n"); 67 html("<table summary='blob content' class='bin-blob'>\n");
68 html("<tr><th>ofs</th><th>hex dump</th><th>ascii</th></tr>"); 68 html("<tr><th>ofs</th><th>hex dump</th><th>ascii</th></tr>");
69 for (ofs = 0; ofs < size; ofs += ROWLEN, buf += ROWLEN) { 69 for (ofs = 0; ofs < size; ofs += ROWLEN, buf += ROWLEN) {
70 htmlf("<tr><td class='right'>%04x</td><td class='hex'>", ofs); 70 htmlf("<tr><td class='right'>%04x</td><td class='hex'>", ofs);
71 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++) 71 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++)
72 htmlf("%*s%02x", 72 htmlf("%*s%02x",
73 idx == 16 ? 4 : 1, "", 73 idx == 16 ? 4 : 1, "",
74 buf[idx] & 0xff); 74 buf[idx] & 0xff);
75 html(" </td><td class='hex'>"); 75 html(" </td><td class='hex'>");
76 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++) 76 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++)
77 ascii[idx] = isgraph(buf[idx]) ? buf[idx] : '.'; 77 ascii[idx] = isgraph(buf[idx]) ? buf[idx] : '.';
78 ascii[idx] = '\0'; 78 ascii[idx] = '\0';
79 html_txt(ascii); 79 html_txt(ascii);
80 html("</td></tr>\n"); 80 html("</td></tr>\n");
81 } 81 }
82 html("</table>\n"); 82 html("</table>\n");
83} 83}
84 84
85static void print_object(const unsigned char *sha1, char *path, const char *basename) 85static void print_object(const unsigned char *sha1, char *path, const char *basename)
86{ 86{
87 enum object_type type; 87 enum object_type type;
88 char *buf; 88 char *buf;
89 unsigned long size; 89 unsigned long size;
90 90
91 type = sha1_object_info(sha1, &size); 91 type = sha1_object_info(sha1, &size);
92 if (type == OBJ_BAD) { 92 if (type == OBJ_BAD) {
93 cgit_print_error(fmt("Bad object name: %s", 93 cgit_print_error(fmt("Bad object name: %s",
94 sha1_to_hex(sha1))); 94 sha1_to_hex(sha1)));
95 return; 95 return;
96 } 96 }
97 97
98 buf = read_sha1_file(sha1, &type, &size); 98 buf = read_sha1_file(sha1, &type, &size);
99 if (!buf) { 99 if (!buf) {
100 cgit_print_error(fmt("Error reading object %s", 100 cgit_print_error(fmt("Error reading object %s",
101 sha1_to_hex(sha1))); 101 sha1_to_hex(sha1)));
102 return; 102 return;
103 } 103 }
104 104
105 html(" ("); 105 html(" (");
106 cgit_plain_link("plain", NULL, NULL, ctx.qry.head, 106 cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
107 curr_rev, path); 107 curr_rev, path);
108 htmlf(")<br/>blob: %s\n", sha1_to_hex(sha1)); 108 htmlf(")<br/>blob: %s\n", sha1_to_hex(sha1));
109 109
110 if (buffer_is_binary(buf, size)) 110 if (buffer_is_binary(buf, size))
111 print_binary_buffer(buf, size); 111 print_binary_buffer(buf, size);
112 else 112 else
113 print_text_buffer(basename, buf, size); 113 print_text_buffer(basename, buf, size);
114} 114}
115 115
116 116
117static int ls_item(const unsigned char *sha1, const char *base, int baselen, 117static int ls_item(const unsigned char *sha1, const char *base, int baselen,
118 const char *pathname, unsigned int mode, int stage, 118 const char *pathname, unsigned int mode, int stage,
119 void *cbdata) 119 void *cbdata)
120{ 120{
121 char *name; 121 char *name;
122 char *fullpath; 122 char *fullpath;
123 char *class; 123 char *class;
124 enum object_type type; 124 enum object_type type;
125 unsigned long size = 0; 125 unsigned long size = 0;
126 126
127 name = xstrdup(pathname); 127 name = xstrdup(pathname);
128 fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "", 128 fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "",
129 ctx.qry.path ? "/" : "", name); 129 ctx.qry.path ? "/" : "", name);
130 130
131 if (!S_ISGITLINK(mode)) { 131 if (!S_ISGITLINK(mode)) {
132 type = sha1_object_info(sha1, &size); 132 type = sha1_object_info(sha1, &size);
133 if (type == OBJ_BAD) { 133 if (type == OBJ_BAD) {
134 htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>", 134 htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>",
135 name, 135 name,
136 sha1_to_hex(sha1)); 136 sha1_to_hex(sha1));
137 return 0; 137 return 0;
138 } 138 }
139 } 139 }
140 140
141 html("<tr><td class='ls-mode'>"); 141 html("<tr><td class='ls-mode'>");
142 cgit_print_filemode(mode); 142 cgit_print_filemode(mode);
143 html("</td><td>"); 143 html("</td><td>");
144 if (S_ISGITLINK(mode)) { 144 if (S_ISGITLINK(mode)) {
145 htmlf("<a class='ls-mod' href='"); 145 htmlf("<a class='ls-mod' href='");
146 html_attr(fmt(ctx.repo->module_link, 146 html_attr(fmt(ctx.repo->module_link,
147 name, 147 name,
148 sha1_to_hex(sha1))); 148 sha1_to_hex(sha1)));
149 html("'>"); 149 html("'>");
150 html_txt(name); 150 html_txt(name);
151 html("</a>"); 151 html("</a>");
152 } else if (S_ISDIR(mode)) { 152 } else if (S_ISDIR(mode)) {
153 cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, 153 cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head,
154 curr_rev, fullpath); 154 curr_rev, fullpath);
155 } else { 155 } else {
156 class = strrchr(name, '.'); 156 class = strrchr(name, '.');
157 if (class != NULL) { 157 if (class != NULL) {
158 class = fmt("ls-blob %s", class + 1); 158 class = fmt("ls-blob %s", class + 1);
159 } else 159 } else
160 class = "ls-blob"; 160 class = "ls-blob";
161 cgit_tree_link(name, NULL, class, ctx.qry.head, 161 cgit_tree_link(name, NULL, class, ctx.qry.head,
162 curr_rev, fullpath); 162 curr_rev, fullpath);
163 } 163 }
164 htmlf("</td><td class='ls-size'>%li</td>", size); 164 htmlf("</td><td class='ls-size'>%li</td>", size);
165 165
166 html("<td>"); 166 html("<td>");
167 cgit_log_link("log", NULL, "button", ctx.qry.head, curr_rev, 167 cgit_log_link("log", NULL, "button", ctx.qry.head, curr_rev,
168 fullpath, 0, NULL, NULL, ctx.qry.showmsg); 168 fullpath, 0, NULL, NULL, ctx.qry.showmsg);
169 if (ctx.repo->max_stats) 169 if (ctx.repo->max_stats)
170 cgit_stats_link("stats", NULL, "button", ctx.qry.head, 170 cgit_stats_link("stats", NULL, "button", ctx.qry.head,
171 fullpath); 171 fullpath);
172 html("</td></tr>\n"); 172 html("</td></tr>\n");
173 free(name); 173 free(name);
174 return 0; 174 return 0;
175} 175}
176 176
177static void ls_head() 177static void ls_head()
178{ 178{
179 html("<table summary='tree listing' class='list'>\n"); 179 html("<table summary='tree listing' class='list'>\n");
180 html("<tr class='nohover'>"); 180 html("<tr class='nohover'>");
181 html("<th class='left'>Mode</th>"); 181 html("<th class='left'>Mode</th>");
182 html("<th class='left'>Name</th>"); 182 html("<th class='left'>Name</th>");
183 html("<th class='right'>Size</th>"); 183 html("<th class='right'>Size</th>");
184 html("<th/>"); 184 html("<th/>");
185 html("</tr>\n"); 185 html("</tr>\n");
186 header = 1; 186 header = 1;
187} 187}
188 188
189static void ls_tail() 189static void ls_tail()
190{ 190{
191 if (!header) 191 if (!header)
192 return; 192 return;
193 html("</table>\n"); 193 html("</table>\n");
194 header = 0; 194 header = 0;
195} 195}
196 196
197static void ls_tree(const unsigned char *sha1, char *path) 197static void ls_tree(const unsigned char *sha1, char *path)
198{ 198{
199 struct tree *tree; 199 struct tree *tree;
200 200
201 tree = parse_tree_indirect(sha1); 201 tree = parse_tree_indirect(sha1);
202 if (!tree) { 202 if (!tree) {
203 cgit_print_error(fmt("Not a tree object: %s", 203 cgit_print_error(fmt("Not a tree object: %s",
204 sha1_to_hex(sha1))); 204 sha1_to_hex(sha1)));
205 return; 205 return;
206 } 206 }
207 207
208 ls_head(); 208 ls_head();
209 read_tree_recursive(tree, "", 0, 1, NULL, ls_item, NULL); 209 read_tree_recursive(tree, "", 0, 1, NULL, ls_item, NULL);
210 ls_tail(); 210 ls_tail();
211} 211}
212 212
213 213
214static int walk_tree(const unsigned char *sha1, const char *base, int baselen, 214static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
215 const char *pathname, unsigned mode, int stage, 215 const char *pathname, unsigned mode, int stage,
216 void *cbdata) 216 void *cbdata)
217{ 217{
218 static int state; 218 static int state;
219 static char buffer[PATH_MAX]; 219 static char buffer[PATH_MAX];
220 char *url; 220 char *url;
221 221
222 if (state == 0) { 222 if (state == 0) {
223 memcpy(buffer, base, baselen); 223 memcpy(buffer, base, baselen);
224 strcpy(buffer+baselen, pathname); 224 strcpy(buffer+baselen, pathname);
225 url = cgit_pageurl(ctx.qry.repo, "tree", 225 url = cgit_pageurl(ctx.qry.repo, "tree",
226 fmt("h=%s&amp;path=%s", curr_rev, buffer)); 226 fmt("h=%s&amp;path=%s", curr_rev, buffer));
227 html("/"); 227 html("/");
228 cgit_tree_link(xstrdup(pathname), NULL, NULL, ctx.qry.head, 228 cgit_tree_link(xstrdup(pathname), NULL, NULL, ctx.qry.head,
229 curr_rev, buffer); 229 curr_rev, buffer);
230 230
231 if (strcmp(match_path, buffer)) 231 if (strcmp(match_path, buffer))
232 return READ_TREE_RECURSIVE; 232 return READ_TREE_RECURSIVE;
233 233
234 if (S_ISDIR(mode)) { 234 if (S_ISDIR(mode)) {
235 state = 1; 235 state = 1;
236 ls_head(); 236 ls_head();
237 return READ_TREE_RECURSIVE; 237 return READ_TREE_RECURSIVE;
238 } else { 238 } else {
239 print_object(sha1, buffer, pathname); 239 print_object(sha1, buffer, pathname);
240 return 0; 240 return 0;
241 } 241 }
242 } 242 }
243 ls_item(sha1, base, baselen, pathname, mode, stage, NULL); 243 ls_item(sha1, base, baselen, pathname, mode, stage, NULL);
244 return 0; 244 return 0;
245} 245}
246 246
247 247
248/* 248/*
249 * Show a tree or a blob 249 * Show a tree or a blob
250 * rev: the commit pointing at the root tree object 250 * rev: the commit pointing at the root tree object
251 * path: path to tree or blob 251 * path: path to tree or blob
252 */ 252 */
253void cgit_print_tree(const char *rev, char *path) 253void cgit_print_tree(const char *rev, char *path)
254{ 254{
255 unsigned char sha1[20]; 255 unsigned char sha1[20];
256 struct commit *commit; 256 struct commit *commit;
257 const char *paths[] = {path, NULL}; 257 const char *paths[] = {path, NULL};
258 258
259 if (!rev) 259 if (!rev)
260 rev = ctx.qry.head; 260 rev = ctx.qry.head;
261 261
262 curr_rev = xstrdup(rev); 262 curr_rev = xstrdup(rev);
263 if (get_sha1(rev, sha1)) { 263 if (get_sha1(rev, sha1)) {
264 cgit_print_error(fmt("Invalid revision name: %s", rev)); 264 cgit_print_error(fmt("Invalid revision name: %s", rev));
265 return; 265 return;
266 } 266 }
267 commit = lookup_commit_reference(sha1); 267 commit = lookup_commit_reference(sha1);
268 if (!commit || parse_commit(commit)) { 268 if (!commit || parse_commit(commit)) {
269 cgit_print_error(fmt("Invalid commit reference: %s", rev)); 269 cgit_print_error(fmt("Invalid commit reference: %s", rev));
270 return; 270 return;
271 } 271 }
272 272
273 html("path: <a href='"); 273 html("path: <a href='");
274 html_attr(cgit_pageurl(ctx.qry.repo, "tree", fmt("h=%s", rev))); 274 html_attr(cgit_pageurl(ctx.qry.repo, "tree", fmt("h=%s", rev)));
275 html("'>root</a>"); 275 html("'>root</a>");
276 276
277 if (path == NULL) { 277 if (path == NULL) {
278 ls_tree(commit->tree->object.sha1, NULL); 278 ls_tree(commit->tree->object.sha1, NULL);
279 return; 279 return;
280 } 280 }
281 281
282 match_path = path; 282 match_path = path;
283 read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree, NULL); 283 read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree, NULL);
284 ls_tail(); 284 ls_tail();
285} 285}