summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c3
-rw-r--r--cgit.css6
-rw-r--r--cgit.h1
-rw-r--r--cgitrc.5.txt4
-rw-r--r--ui-tree.c35
5 files changed, 32 insertions, 17 deletions
diff --git a/cgit.c b/cgit.c
index b0e1c44..ec40e1f 100644
--- a/cgit.c
+++ b/cgit.c
@@ -57,64 +57,66 @@ void config_cb(const char *name, const char *value)
57 else if (!strcmp(name, "head-include")) 57 else if (!strcmp(name, "head-include"))
58 ctx.cfg.head_include = xstrdup(value); 58 ctx.cfg.head_include = xstrdup(value);
59 else if (!strcmp(name, "header")) 59 else if (!strcmp(name, "header"))
60 ctx.cfg.header = xstrdup(value); 60 ctx.cfg.header = xstrdup(value);
61 else if (!strcmp(name, "logo")) 61 else if (!strcmp(name, "logo"))
62 ctx.cfg.logo = xstrdup(value); 62 ctx.cfg.logo = xstrdup(value);
63 else if (!strcmp(name, "index-header")) 63 else if (!strcmp(name, "index-header"))
64 ctx.cfg.index_header = xstrdup(value); 64 ctx.cfg.index_header = xstrdup(value);
65 else if (!strcmp(name, "index-info")) 65 else if (!strcmp(name, "index-info"))
66 ctx.cfg.index_info = xstrdup(value); 66 ctx.cfg.index_info = xstrdup(value);
67 else if (!strcmp(name, "logo-link")) 67 else if (!strcmp(name, "logo-link"))
68 ctx.cfg.logo_link = xstrdup(value); 68 ctx.cfg.logo_link = xstrdup(value);
69 else if (!strcmp(name, "module-link")) 69 else if (!strcmp(name, "module-link"))
70 ctx.cfg.module_link = xstrdup(value); 70 ctx.cfg.module_link = xstrdup(value);
71 else if (!strcmp(name, "virtual-root")) { 71 else if (!strcmp(name, "virtual-root")) {
72 ctx.cfg.virtual_root = trim_end(value, '/'); 72 ctx.cfg.virtual_root = trim_end(value, '/');
73 if (!ctx.cfg.virtual_root && (!strcmp(value, "/"))) 73 if (!ctx.cfg.virtual_root && (!strcmp(value, "/")))
74 ctx.cfg.virtual_root = ""; 74 ctx.cfg.virtual_root = "";
75 } else if (!strcmp(name, "nocache")) 75 } else if (!strcmp(name, "nocache"))
76 ctx.cfg.nocache = atoi(value); 76 ctx.cfg.nocache = atoi(value);
77 else if (!strcmp(name, "noplainemail")) 77 else if (!strcmp(name, "noplainemail"))
78 ctx.cfg.noplainemail = atoi(value); 78 ctx.cfg.noplainemail = atoi(value);
79 else if (!strcmp(name, "noheader")) 79 else if (!strcmp(name, "noheader"))
80 ctx.cfg.noheader = atoi(value); 80 ctx.cfg.noheader = atoi(value);
81 else if (!strcmp(name, "snapshots")) 81 else if (!strcmp(name, "snapshots"))
82 ctx.cfg.snapshots = cgit_parse_snapshots_mask(value); 82 ctx.cfg.snapshots = cgit_parse_snapshots_mask(value);
83 else if (!strcmp(name, "enable-index-links")) 83 else if (!strcmp(name, "enable-index-links"))
84 ctx.cfg.enable_index_links = atoi(value); 84 ctx.cfg.enable_index_links = atoi(value);
85 else if (!strcmp(name, "enable-log-filecount")) 85 else if (!strcmp(name, "enable-log-filecount"))
86 ctx.cfg.enable_log_filecount = atoi(value); 86 ctx.cfg.enable_log_filecount = atoi(value);
87 else if (!strcmp(name, "enable-log-linecount")) 87 else if (!strcmp(name, "enable-log-linecount"))
88 ctx.cfg.enable_log_linecount = atoi(value); 88 ctx.cfg.enable_log_linecount = atoi(value);
89 else if (!strcmp(name, "enable-tree-linenumbers"))
90 ctx.cfg.enable_tree_linenumbers = atoi(value);
89 else if (!strcmp(name, "max-stats")) 91 else if (!strcmp(name, "max-stats"))
90 ctx.cfg.max_stats = cgit_find_stats_period(value, NULL); 92 ctx.cfg.max_stats = cgit_find_stats_period(value, NULL);
91 else if (!strcmp(name, "cache-size")) 93 else if (!strcmp(name, "cache-size"))
92 ctx.cfg.cache_size = atoi(value); 94 ctx.cfg.cache_size = atoi(value);
93 else if (!strcmp(name, "cache-root")) 95 else if (!strcmp(name, "cache-root"))
94 ctx.cfg.cache_root = xstrdup(value); 96 ctx.cfg.cache_root = xstrdup(value);
95 else if (!strcmp(name, "cache-root-ttl")) 97 else if (!strcmp(name, "cache-root-ttl"))
96 ctx.cfg.cache_root_ttl = atoi(value); 98 ctx.cfg.cache_root_ttl = atoi(value);
97 else if (!strcmp(name, "cache-repo-ttl")) 99 else if (!strcmp(name, "cache-repo-ttl"))
98 ctx.cfg.cache_repo_ttl = atoi(value); 100 ctx.cfg.cache_repo_ttl = atoi(value);
99 else if (!strcmp(name, "cache-static-ttl")) 101 else if (!strcmp(name, "cache-static-ttl"))
100 ctx.cfg.cache_static_ttl = atoi(value); 102 ctx.cfg.cache_static_ttl = atoi(value);
101 else if (!strcmp(name, "cache-dynamic-ttl")) 103 else if (!strcmp(name, "cache-dynamic-ttl"))
102 ctx.cfg.cache_dynamic_ttl = atoi(value); 104 ctx.cfg.cache_dynamic_ttl = atoi(value);
103 else if (!strcmp(name, "about-filter")) 105 else if (!strcmp(name, "about-filter"))
104 ctx.cfg.about_filter = new_filter(value, 0); 106 ctx.cfg.about_filter = new_filter(value, 0);
105 else if (!strcmp(name, "commit-filter")) 107 else if (!strcmp(name, "commit-filter"))
106 ctx.cfg.commit_filter = new_filter(value, 0); 108 ctx.cfg.commit_filter = new_filter(value, 0);
107 else if (!strcmp(name, "embedded")) 109 else if (!strcmp(name, "embedded"))
108 ctx.cfg.embedded = atoi(value); 110 ctx.cfg.embedded = atoi(value);
109 else if (!strcmp(name, "max-message-length")) 111 else if (!strcmp(name, "max-message-length"))
110 ctx.cfg.max_msg_len = atoi(value); 112 ctx.cfg.max_msg_len = atoi(value);
111 else if (!strcmp(name, "max-repodesc-length")) 113 else if (!strcmp(name, "max-repodesc-length"))
112 ctx.cfg.max_repodesc_len = atoi(value); 114 ctx.cfg.max_repodesc_len = atoi(value);
113 else if (!strcmp(name, "max-repo-count")) 115 else if (!strcmp(name, "max-repo-count"))
114 ctx.cfg.max_repo_count = atoi(value); 116 ctx.cfg.max_repo_count = atoi(value);
115 else if (!strcmp(name, "max-commit-count")) 117 else if (!strcmp(name, "max-commit-count"))
116 ctx.cfg.max_commit_count = atoi(value); 118 ctx.cfg.max_commit_count = atoi(value);
117 else if (!strcmp(name, "source-filter")) 119 else if (!strcmp(name, "source-filter"))
118 ctx.cfg.source_filter = new_filter(value, 1); 120 ctx.cfg.source_filter = new_filter(value, 1);
119 else if (!strcmp(name, "summary-log")) 121 else if (!strcmp(name, "summary-log"))
120 ctx.cfg.summary_log = atoi(value); 122 ctx.cfg.summary_log = atoi(value);
@@ -209,64 +211,65 @@ static void querystring_cb(const char *name, const char *value)
209 ctx.qry.name = xstrdup(value); 211 ctx.qry.name = xstrdup(value);
210 } else if (!strcmp(name, "mimetype")) { 212 } else if (!strcmp(name, "mimetype")) {
211 ctx.qry.mimetype = xstrdup(value); 213 ctx.qry.mimetype = xstrdup(value);
212 } else if (!strcmp(name, "s")){ 214 } else if (!strcmp(name, "s")){
213 ctx.qry.sort = xstrdup(value); 215 ctx.qry.sort = xstrdup(value);
214 } else if (!strcmp(name, "showmsg")) { 216 } else if (!strcmp(name, "showmsg")) {
215 ctx.qry.showmsg = atoi(value); 217 ctx.qry.showmsg = atoi(value);
216 } else if (!strcmp(name, "period")) { 218 } else if (!strcmp(name, "period")) {
217 ctx.qry.period = xstrdup(value); 219 ctx.qry.period = xstrdup(value);
218 } 220 }
219} 221}
220 222
221char *xstrdupn(const char *str) 223char *xstrdupn(const char *str)
222{ 224{
223 return (str ? xstrdup(str) : NULL); 225 return (str ? xstrdup(str) : NULL);
224} 226}
225 227
226static void prepare_context(struct cgit_context *ctx) 228static void prepare_context(struct cgit_context *ctx)
227{ 229{
228 memset(ctx, 0, sizeof(ctx)); 230 memset(ctx, 0, sizeof(ctx));
229 ctx->cfg.agefile = "info/web/last-modified"; 231 ctx->cfg.agefile = "info/web/last-modified";
230 ctx->cfg.nocache = 0; 232 ctx->cfg.nocache = 0;
231 ctx->cfg.cache_size = 0; 233 ctx->cfg.cache_size = 0;
232 ctx->cfg.cache_dynamic_ttl = 5; 234 ctx->cfg.cache_dynamic_ttl = 5;
233 ctx->cfg.cache_max_create_time = 5; 235 ctx->cfg.cache_max_create_time = 5;
234 ctx->cfg.cache_repo_ttl = 5; 236 ctx->cfg.cache_repo_ttl = 5;
235 ctx->cfg.cache_root = CGIT_CACHE_ROOT; 237 ctx->cfg.cache_root = CGIT_CACHE_ROOT;
236 ctx->cfg.cache_root_ttl = 5; 238 ctx->cfg.cache_root_ttl = 5;
237 ctx->cfg.cache_static_ttl = -1; 239 ctx->cfg.cache_static_ttl = -1;
238 ctx->cfg.css = "/cgit.css"; 240 ctx->cfg.css = "/cgit.css";
239 ctx->cfg.logo = "/cgit.png"; 241 ctx->cfg.logo = "/cgit.png";
240 ctx->cfg.local_time = 0; 242 ctx->cfg.local_time = 0;
243 ctx->cfg.enable_tree_linenumbers = 1;
241 ctx->cfg.max_repo_count = 50; 244 ctx->cfg.max_repo_count = 50;
242 ctx->cfg.max_commit_count = 50; 245 ctx->cfg.max_commit_count = 50;
243 ctx->cfg.max_lock_attempts = 5; 246 ctx->cfg.max_lock_attempts = 5;
244 ctx->cfg.max_msg_len = 80; 247 ctx->cfg.max_msg_len = 80;
245 ctx->cfg.max_repodesc_len = 80; 248 ctx->cfg.max_repodesc_len = 80;
246 ctx->cfg.max_stats = 0; 249 ctx->cfg.max_stats = 0;
247 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; 250 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
248 ctx->cfg.renamelimit = -1; 251 ctx->cfg.renamelimit = -1;
249 ctx->cfg.robots = "index, nofollow"; 252 ctx->cfg.robots = "index, nofollow";
250 ctx->cfg.root_title = "Git repository browser"; 253 ctx->cfg.root_title = "Git repository browser";
251 ctx->cfg.root_desc = "a fast webinterface for the git dscm"; 254 ctx->cfg.root_desc = "a fast webinterface for the git dscm";
252 ctx->cfg.script_name = CGIT_SCRIPT_NAME; 255 ctx->cfg.script_name = CGIT_SCRIPT_NAME;
253 ctx->cfg.summary_branches = 10; 256 ctx->cfg.summary_branches = 10;
254 ctx->cfg.summary_log = 10; 257 ctx->cfg.summary_log = 10;
255 ctx->cfg.summary_tags = 10; 258 ctx->cfg.summary_tags = 10;
256 ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG")); 259 ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG"));
257 ctx->env.http_host = xstrdupn(getenv("HTTP_HOST")); 260 ctx->env.http_host = xstrdupn(getenv("HTTP_HOST"));
258 ctx->env.https = xstrdupn(getenv("HTTPS")); 261 ctx->env.https = xstrdupn(getenv("HTTPS"));
259 ctx->env.no_http = xstrdupn(getenv("NO_HTTP")); 262 ctx->env.no_http = xstrdupn(getenv("NO_HTTP"));
260 ctx->env.path_info = xstrdupn(getenv("PATH_INFO")); 263 ctx->env.path_info = xstrdupn(getenv("PATH_INFO"));
261 ctx->env.query_string = xstrdupn(getenv("QUERY_STRING")); 264 ctx->env.query_string = xstrdupn(getenv("QUERY_STRING"));
262 ctx->env.request_method = xstrdupn(getenv("REQUEST_METHOD")); 265 ctx->env.request_method = xstrdupn(getenv("REQUEST_METHOD"));
263 ctx->env.script_name = xstrdupn(getenv("SCRIPT_NAME")); 266 ctx->env.script_name = xstrdupn(getenv("SCRIPT_NAME"));
264 ctx->env.server_name = xstrdupn(getenv("SERVER_NAME")); 267 ctx->env.server_name = xstrdupn(getenv("SERVER_NAME"));
265 ctx->env.server_port = xstrdupn(getenv("SERVER_PORT")); 268 ctx->env.server_port = xstrdupn(getenv("SERVER_PORT"));
266 ctx->page.mimetype = "text/html"; 269 ctx->page.mimetype = "text/html";
267 ctx->page.charset = PAGE_ENCODING; 270 ctx->page.charset = PAGE_ENCODING;
268 ctx->page.filename = NULL; 271 ctx->page.filename = NULL;
269 ctx->page.size = 0; 272 ctx->page.size = 0;
270 ctx->page.modified = time(NULL); 273 ctx->page.modified = time(NULL);
271 ctx->page.expires = ctx->page.modified; 274 ctx->page.expires = ctx->page.modified;
272 ctx->page.etag = NULL; 275 ctx->page.etag = NULL;
diff --git a/cgit.css b/cgit.css
index e3b32e7..ebf3322 100644
--- a/cgit.css
+++ b/cgit.css
@@ -208,74 +208,74 @@ table#downloads th {
208 208
209div#blob { 209div#blob {
210 border: solid 1px black; 210 border: solid 1px black;
211} 211}
212 212
213div.error { 213div.error {
214 color: red; 214 color: red;
215 font-weight: bold; 215 font-weight: bold;
216 margin: 1em 2em; 216 margin: 1em 2em;
217} 217}
218 218
219a.ls-blob, a.ls-dir, a.ls-mod { 219a.ls-blob, a.ls-dir, a.ls-mod {
220 font-family: monospace; 220 font-family: monospace;
221} 221}
222 222
223td.ls-size { 223td.ls-size {
224 text-align: right; 224 text-align: right;
225 font-family: monospace; 225 font-family: monospace;
226 width: 10em; 226 width: 10em;
227} 227}
228 228
229td.ls-mode { 229td.ls-mode {
230 font-family: monospace; 230 font-family: monospace;
231 width: 10em; 231 width: 10em;
232} 232}
233 233
234table.blob { 234table.blob {
235 margin-top: 0.5em; 235 margin-top: 0.5em;
236 border-top: solid 1px black; 236 border-top: solid 1px black;
237} 237}
238 238
239table.blob td.lines { 239table.blob td.lines {
240 margin: 0; padding: 0; 240 margin: 0; padding: 0 0 0 0.5em;
241 vertical-align: top; 241 vertical-align: top;
242 color: black; 242 color: black;
243} 243}
244 244
245table.blob td.linenumbers { 245table.blob td.linenumbers {
246 margin: 0; padding: 0; 246 margin: 0; padding: 0 0.5em 0 0.5em;
247 vertical-align: top; 247 vertical-align: top;
248 text-align: right;
248 border-right: 1px solid gray; 249 border-right: 1px solid gray;
249 background-color: #eee;
250} 250}
251 251
252table.blob pre { 252table.blob pre {
253 padding: 0; margin: 0; 253 padding: 0; margin: 0;
254} 254}
255 255
256table.blob a.no { 256table.blob a.no {
257 color: gray; 257 color: gray;
258 text-align: right; 258 text-align: right;
259 text-decoration: none; 259 text-decoration: none;
260} 260}
261 261
262table.blob a.no a:hover { 262table.blob a.no a:hover {
263 color: black; 263 color: black;
264} 264}
265 265
266table.bin-blob { 266table.bin-blob {
267 margin-top: 0.5em; 267 margin-top: 0.5em;
268 border: solid 1px black; 268 border: solid 1px black;
269} 269}
270 270
271table.bin-blob th { 271table.bin-blob th {
272 font-family: monospace; 272 font-family: monospace;
273 white-space: pre; 273 white-space: pre;
274 border: solid 1px #777; 274 border: solid 1px #777;
275 padding: 0.5em 1em; 275 padding: 0.5em 1em;
276} 276}
277 277
278table.bin-blob td { 278table.bin-blob td {
279 font-family: monospace; 279 font-family: monospace;
280 white-space: pre; 280 white-space: pre;
281 border-left: solid 1px #777; 281 border-left: solid 1px #777;
diff --git a/cgit.h b/cgit.h
index adb8da4..a20679a 100644
--- a/cgit.h
+++ b/cgit.h
@@ -144,64 +144,65 @@ struct cgit_query {
144 144
145struct cgit_config { 145struct cgit_config {
146 char *agefile; 146 char *agefile;
147 char *cache_root; 147 char *cache_root;
148 char *clone_prefix; 148 char *clone_prefix;
149 char *css; 149 char *css;
150 char *favicon; 150 char *favicon;
151 char *footer; 151 char *footer;
152 char *head_include; 152 char *head_include;
153 char *header; 153 char *header;
154 char *index_header; 154 char *index_header;
155 char *index_info; 155 char *index_info;
156 char *logo; 156 char *logo;
157 char *logo_link; 157 char *logo_link;
158 char *module_link; 158 char *module_link;
159 char *repo_group; 159 char *repo_group;
160 char *robots; 160 char *robots;
161 char *root_title; 161 char *root_title;
162 char *root_desc; 162 char *root_desc;
163 char *root_readme; 163 char *root_readme;
164 char *script_name; 164 char *script_name;
165 char *virtual_root; 165 char *virtual_root;
166 int cache_size; 166 int cache_size;
167 int cache_dynamic_ttl; 167 int cache_dynamic_ttl;
168 int cache_max_create_time; 168 int cache_max_create_time;
169 int cache_repo_ttl; 169 int cache_repo_ttl;
170 int cache_root_ttl; 170 int cache_root_ttl;
171 int cache_static_ttl; 171 int cache_static_ttl;
172 int embedded; 172 int embedded;
173 int enable_index_links; 173 int enable_index_links;
174 int enable_log_filecount; 174 int enable_log_filecount;
175 int enable_log_linecount; 175 int enable_log_linecount;
176 int enable_tree_linenumbers;
176 int local_time; 177 int local_time;
177 int max_repo_count; 178 int max_repo_count;
178 int max_commit_count; 179 int max_commit_count;
179 int max_lock_attempts; 180 int max_lock_attempts;
180 int max_msg_len; 181 int max_msg_len;
181 int max_repodesc_len; 182 int max_repodesc_len;
182 int max_stats; 183 int max_stats;
183 int nocache; 184 int nocache;
184 int noplainemail; 185 int noplainemail;
185 int noheader; 186 int noheader;
186 int renamelimit; 187 int renamelimit;
187 int snapshots; 188 int snapshots;
188 int summary_branches; 189 int summary_branches;
189 int summary_log; 190 int summary_log;
190 int summary_tags; 191 int summary_tags;
191 struct string_list mimetypes; 192 struct string_list mimetypes;
192 struct cgit_filter *about_filter; 193 struct cgit_filter *about_filter;
193 struct cgit_filter *commit_filter; 194 struct cgit_filter *commit_filter;
194 struct cgit_filter *source_filter; 195 struct cgit_filter *source_filter;
195}; 196};
196 197
197struct cgit_page { 198struct cgit_page {
198 time_t modified; 199 time_t modified;
199 time_t expires; 200 time_t expires;
200 size_t size; 201 size_t size;
201 char *mimetype; 202 char *mimetype;
202 char *charset; 203 char *charset;
203 char *filename; 204 char *filename;
204 char *etag; 205 char *etag;
205 char *title; 206 char *title;
206 int status; 207 int status;
207 char *statusmsg; 208 char *statusmsg;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 0d18290..3b16db9 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -70,64 +70,68 @@ clone-prefix::
70 none. 70 none.
71 71
72commit-filter:: 72commit-filter::
73 Specifies a command which will be invoked to format commit messages. 73 Specifies a command which will be invoked to format commit messages.
74 The command will get the message on its STDIN, and the STDOUT from the 74 The command will get the message on its STDIN, and the STDOUT from the
75 command will be included verbatim as the commit message, i.e. this can 75 command will be included verbatim as the commit message, i.e. this can
76 be used to implement bugtracker integration. Default value: none. 76 be used to implement bugtracker integration. Default value: none.
77 77
78css:: 78css::
79 Url which specifies the css document to include in all cgit pages. 79 Url which specifies the css document to include in all cgit pages.
80 Default value: "/cgit.css". 80 Default value: "/cgit.css".
81 81
82embedded:: 82embedded::
83 Flag which, when set to "1", will make cgit generate a html fragment 83 Flag which, when set to "1", will make cgit generate a html fragment
84 suitable for embedding in other html pages. Default value: none. See 84 suitable for embedding in other html pages. Default value: none. See
85 also: "noheader". 85 also: "noheader".
86 86
87enable-index-links:: 87enable-index-links::
88 Flag which, when set to "1", will make cgit generate extra links for 88 Flag which, when set to "1", will make cgit generate extra links for
89 each repo in the repository index (specifically, to the "summary", 89 each repo in the repository index (specifically, to the "summary",
90 "commit" and "tree" pages). Default value: "0". 90 "commit" and "tree" pages). Default value: "0".
91 91
92enable-log-filecount:: 92enable-log-filecount::
93 Flag which, when set to "1", will make cgit print the number of 93 Flag which, when set to "1", will make cgit print the number of
94 modified files for each commit on the repository log page. Default 94 modified files for each commit on the repository log page. Default
95 value: "0". 95 value: "0".
96 96
97enable-log-linecount:: 97enable-log-linecount::
98 Flag which, when set to "1", will make cgit print the number of added 98 Flag which, when set to "1", will make cgit print the number of added
99 and removed lines for each commit on the repository log page. Default 99 and removed lines for each commit on the repository log page. Default
100 value: "0". 100 value: "0".
101 101
102enable-tree-linenumbers::
103 Flag which, when set to "1", will make cgit generate linenumber links
104 for plaintext blobs printed in the tree view. Default value: "1".
105
102favicon:: 106favicon::
103 Url used as link to a shortcut icon for cgit. If specified, it is 107 Url used as link to a shortcut icon for cgit. If specified, it is
104 suggested to use the value "/favicon.ico" since certain browsers will 108 suggested to use the value "/favicon.ico" since certain browsers will
105 ignore other values. Default value: none. 109 ignore other values. Default value: none.
106 110
107footer:: 111footer::
108 The content of the file specified with this option will be included 112 The content of the file specified with this option will be included
109 verbatim at the bottom of all pages (i.e. it replaces the standard 113 verbatim at the bottom of all pages (i.e. it replaces the standard
110 "generated by..." message. Default value: none. 114 "generated by..." message. Default value: none.
111 115
112head-include:: 116head-include::
113 The content of the file specified with this option will be included 117 The content of the file specified with this option will be included
114 verbatim in the html HEAD section on all pages. Default value: none. 118 verbatim in the html HEAD section on all pages. Default value: none.
115 119
116header:: 120header::
117 The content of the file specified with this option will be included 121 The content of the file specified with this option will be included
118 verbatim at the top of all pages. Default value: none. 122 verbatim at the top of all pages. Default value: none.
119 123
120include:: 124include::
121 Name of a configfile to include before the rest of the current config- 125 Name of a configfile to include before the rest of the current config-
122 file is parsed. Default value: none. 126 file is parsed. Default value: none.
123 127
124index-header:: 128index-header::
125 The content of the file specified with this option will be included 129 The content of the file specified with this option will be included
126 verbatim above the repository index. This setting is deprecated, and 130 verbatim above the repository index. This setting is deprecated, and
127 will not be supported by cgit-1.0 (use root-readme instead). Default 131 will not be supported by cgit-1.0 (use root-readme instead). Default
128 value: none. 132 value: none.
129 133
130index-info:: 134index-info::
131 The content of the file specified with this option will be included 135 The content of the file specified with this option will be included
132 verbatim below the heading on the repository index page. This setting 136 verbatim below the heading on the repository index page. This setting
133 is deprecated, and will not be supported by cgit-1.0 (use root-desc 137 is deprecated, and will not be supported by cgit-1.0 (use root-desc
diff --git a/ui-tree.c b/ui-tree.c
index c608754..f53ab64 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -1,79 +1,86 @@
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
26 if (ctx.cfg.enable_tree_linenumbers) {
27 html("<tr><td class='linenumbers'><pre>");
28 idx = 0;
29 lineno = 0;
30
31 if (size) {
32 htmlf(numberfmt, ++lineno);
33 while(idx < size - 1) { // skip absolute last newline
34 if (buf[idx] == '\n')
35 htmlf(numberfmt, ++lineno);
36 idx++;
37 }
38 }
39 html("</pre></td>\n");
40 }
41 else {
42 html("<tr>\n");
43 }
44
25 if (ctx.repo->source_filter) { 45 if (ctx.repo->source_filter) {
26 html("<tr><td class='lines'><pre><code>"); 46 html("<td class='lines'><pre><code>");
27 ctx.repo->source_filter->argv[1] = xstrdup(name); 47 ctx.repo->source_filter->argv[1] = xstrdup(name);
28 cgit_open_filter(ctx.repo->source_filter); 48 cgit_open_filter(ctx.repo->source_filter);
29 write(STDOUT_FILENO, buf, size); 49 write(STDOUT_FILENO, buf, size);
30 cgit_close_filter(ctx.repo->source_filter); 50 cgit_close_filter(ctx.repo->source_filter);
31 html("</code></pre></td></tr></table>\n"); 51 html("</code></pre></td></tr></table>\n");
32 return; 52 return;
33 } 53 }
34 54
35 html("<tr><td class='linenumbers'><pre>");
36 idx = 0;
37 lineno = 0;
38
39 if (size) {
40 htmlf(numberfmt, ++lineno);
41 while(idx < size - 1) { // skip absolute last newline
42 if (buf[idx] == '\n')
43 htmlf(numberfmt, ++lineno);
44 idx++;
45 }
46 }
47 html("</pre></td>\n");
48 html("<td class='lines'><pre><code>"); 55 html("<td class='lines'><pre><code>");
49 html_txt(buf); 56 html_txt(buf);
50 html("</code></pre></td></tr></table>\n"); 57 html("</code></pre></td></tr></table>\n");
51} 58}
52 59
53#define ROWLEN 32 60#define ROWLEN 32
54 61
55static void print_binary_buffer(char *buf, unsigned long size) 62static void print_binary_buffer(char *buf, unsigned long size)
56{ 63{
57 unsigned long ofs, idx; 64 unsigned long ofs, idx;
58 static char ascii[ROWLEN + 1]; 65 static char ascii[ROWLEN + 1];
59 66
60 html("<table summary='blob content' class='bin-blob'>\n"); 67 html("<table summary='blob content' class='bin-blob'>\n");
61 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>");
62 for (ofs = 0; ofs < size; ofs += ROWLEN, buf += ROWLEN) { 69 for (ofs = 0; ofs < size; ofs += ROWLEN, buf += ROWLEN) {
63 htmlf("<tr><td class='right'>%04x</td><td class='hex'>", ofs); 70 htmlf("<tr><td class='right'>%04x</td><td class='hex'>", ofs);
64 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++) 71 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++)
65 htmlf("%*s%02x", 72 htmlf("%*s%02x",
66 idx == 16 ? 4 : 1, "", 73 idx == 16 ? 4 : 1, "",
67 buf[idx] & 0xff); 74 buf[idx] & 0xff);
68 html(" </td><td class='hex'>"); 75 html(" </td><td class='hex'>");
69 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++) 76 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++)
70 ascii[idx] = isgraph(buf[idx]) ? buf[idx] : '.'; 77 ascii[idx] = isgraph(buf[idx]) ? buf[idx] : '.';
71 ascii[idx] = '\0'; 78 ascii[idx] = '\0';
72 html_txt(ascii); 79 html_txt(ascii);
73 html("</td></tr>\n"); 80 html("</td></tr>\n");
74 } 81 }
75 html("</table>\n"); 82 html("</table>\n");
76} 83}
77 84
78static 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)
79{ 86{