summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile5
-rw-r--r--cgit.css11
-rw-r--r--cgit.h7
-rw-r--r--parsing.c25
-rw-r--r--shared.c2
-rw-r--r--ui-log.c21
-rw-r--r--ui-shared.c2
7 files changed, 55 insertions, 18 deletions
diff --git a/Makefile b/Makefile
index 27e966d..685e662 100644
--- a/Makefile
+++ b/Makefile
@@ -14,16 +14,21 @@ GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2
14 14
15 15
16EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto 16EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto
17OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \ 17OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \
18 ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \ 18 ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \
19 ui-snapshot.o ui-blob.o ui-tag.o ui-refs.o 19 ui-snapshot.o ui-blob.o ui-tag.o ui-refs.o
20 20
21 21
22ifdef NEEDS_LIBICONV
23 EXTLIBS += -liconv
24endif
25
26
22.PHONY: all git install clean distclean emptycache force-version get-git 27.PHONY: all git install clean distclean emptycache force-version get-git
23 28
24all: cgit git 29all: cgit git
25 30
26VERSION: force-version 31VERSION: force-version
27 @./gen-version.sh "$(CGIT_VERSION)" 32 @./gen-version.sh "$(CGIT_VERSION)"
28-include VERSION 33-include VERSION
29 34
diff --git a/cgit.css b/cgit.css
index 1b2e9d6..f1003b4 100644
--- a/cgit.css
+++ b/cgit.css
@@ -104,17 +104,17 @@ div#sidebar div.infobox {
104 background-color: #ccc; 104 background-color: #ccc;
105 border-top: solid 1px #eee; 105 border-top: solid 1px #eee;
106 border-left: solid 1px #eee; 106 border-left: solid 1px #eee;
107 border-right: solid 1px #aaa; 107 border-right: solid 1px #aaa;
108 border-bottom: solid 1px #aaa; 108 border-bottom: solid 1px #aaa;
109} 109}
110 110
111div#sidebar div.infobox h1 { 111div#sidebar div.infobox h1 {
112 font-size: 11pt; 112 font-size: 10pt;
113 font-weight: bold; 113 font-weight: bold;
114 margin: 0px; 114 margin: 0px;
115} 115}
116 116
117div#sidebar div.infobox a.menu { 117div#sidebar div.infobox a.menu {
118 display: block; 118 display: block;
119 background-color: #ccc; 119 background-color: #ccc;
120 padding: 0.1em 0.5em; 120 padding: 0.1em 0.5em;
@@ -123,40 +123,31 @@ div#sidebar div.infobox a.menu {
123 123
124div#sidebar div.infobox a.menu:hover { 124div#sidebar div.infobox a.menu:hover {
125 background-color: #bbb; 125 background-color: #bbb;
126 text-decoration: none; 126 text-decoration: none;
127} 127}
128 128
129div#sidebar div.infobox select { 129div#sidebar div.infobox select {
130 width: 100%; 130 width: 100%;
131 border: solid 1px #aaa;
132 background-color: #bbb;
133 margin: 2px 0px 0px 0px; 131 margin: 2px 0px 0px 0px;
134 padding: 0px;
135} 132}
136 133
137td#branch-dropdown-cell { 134td#branch-dropdown-cell {
138 width: 99%; 135 width: 99%;
139} 136}
140 137
141input#switch-btn { 138input#switch-btn {
142 width: 20px; 139 width: 20px;
143 border: solid 1px #aaa;
144 background-color: #bbb;
145 margin: 2px 0px 0px 0px; 140 margin: 2px 0px 0px 0px;
146 padding: 0px;
147} 141}
148 142
149div#sidebar div.infobox input.txt { 143div#sidebar div.infobox input.txt {
150 width: 100%; 144 width: 100%;
151 border: solid 1px #aaa;
152 background-color: #bbb;
153 margin: 2px 0px 0px 0px; 145 margin: 2px 0px 0px 0px;
154 padding: 0;
155} 146}
156 147
157table#grid { 148table#grid {
158 margin: 0px; 149 margin: 0px;
159} 150}
160 151
161td#content { 152td#content {
162 vertical-align: top; 153 vertical-align: top;
diff --git a/cgit.h b/cgit.h
index 163f355..6291c58 100644
--- a/cgit.h
+++ b/cgit.h
@@ -11,16 +11,17 @@
11#include <tag.h> 11#include <tag.h>
12#include <diff.h> 12#include <diff.h>
13#include <diffcore.h> 13#include <diffcore.h>
14#include <refs.h> 14#include <refs.h>
15#include <revision.h> 15#include <revision.h>
16#include <log-tree.h> 16#include <log-tree.h>
17#include <archive.h> 17#include <archive.h>
18#include <xdiff/xdiff.h> 18#include <xdiff/xdiff.h>
19#include <utf8.h>
19 20
20 21
21/* 22/*
22 * The valid cgit repo-commands 23 * The valid cgit repo-commands
23 */ 24 */
24#define CMD_LOG 1 25#define CMD_LOG 1
25#define CMD_COMMIT 2 26#define CMD_COMMIT 2
26#define CMD_DIFF 3 27#define CMD_DIFF 3
@@ -43,16 +44,21 @@
43#define TM_MIN 60 44#define TM_MIN 60
44#define TM_HOUR (TM_MIN * 60) 45#define TM_HOUR (TM_MIN * 60)
45#define TM_DAY (TM_HOUR * 24) 46#define TM_DAY (TM_HOUR * 24)
46#define TM_WEEK (TM_DAY * 7) 47#define TM_WEEK (TM_DAY * 7)
47#define TM_YEAR (TM_DAY * 365) 48#define TM_YEAR (TM_DAY * 365)
48#define TM_MONTH (TM_YEAR / 12.0) 49#define TM_MONTH (TM_YEAR / 12.0)
49 50
50 51
52/*
53 * Default encoding
54 */
55#define PAGE_ENCODING "UTF-8"
56
51typedef void (*configfn)(const char *name, const char *value); 57typedef void (*configfn)(const char *name, const char *value);
52typedef void (*filepair_fn)(struct diff_filepair *pair); 58typedef void (*filepair_fn)(struct diff_filepair *pair);
53typedef void (*linediff_fn)(char *line, int len); 59typedef void (*linediff_fn)(char *line, int len);
54 60
55struct cacheitem { 61struct cacheitem {
56 char *name; 62 char *name;
57 struct stat st; 63 struct stat st;
58 int ttl; 64 int ttl;
@@ -85,16 +91,17 @@ struct commitinfo {
85 char *author; 91 char *author;
86 char *author_email; 92 char *author_email;
87 unsigned long author_date; 93 unsigned long author_date;
88 char *committer; 94 char *committer;
89 char *committer_email; 95 char *committer_email;
90 unsigned long committer_date; 96 unsigned long committer_date;
91 char *subject; 97 char *subject;
92 char *msg; 98 char *msg;
99 char *msg_encoding;
93}; 100};
94 101
95struct taginfo { 102struct taginfo {
96 char *tagger; 103 char *tagger;
97 char *tagger_email; 104 char *tagger_email;
98 int tagger_date; 105 int tagger_date;
99 char *msg; 106 char *msg;
100}; 107};
diff --git a/parsing.c b/parsing.c
index 30e7648..e8c7ab9 100644
--- a/parsing.c
+++ b/parsing.c
@@ -194,16 +194,17 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
194 ret = xmalloc(sizeof(*ret)); 194 ret = xmalloc(sizeof(*ret));
195 ret->commit = commit; 195 ret->commit = commit;
196 ret->author = NULL; 196 ret->author = NULL;
197 ret->author_email = NULL; 197 ret->author_email = NULL;
198 ret->committer = NULL; 198 ret->committer = NULL;
199 ret->committer_email = NULL; 199 ret->committer_email = NULL;
200 ret->subject = NULL; 200 ret->subject = NULL;
201 ret->msg = NULL; 201 ret->msg = NULL;
202 ret->msg_encoding = NULL;
202 203
203 if (p == NULL) 204 if (p == NULL)
204 return ret; 205 return ret;
205 206
206 if (strncmp(p, "tree ", 5)) 207 if (strncmp(p, "tree ", 5))
207 die("Bad commit: %s", sha1_to_hex(commit->object.sha1)); 208 die("Bad commit: %s", sha1_to_hex(commit->object.sha1));
208 else 209 else
209 p += 46; // "tree " + hex[40] + "\n" 210 p += 46; // "tree " + hex[40] + "\n"
@@ -228,16 +229,24 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
228 ret->committer = substr(p, t); 229 ret->committer = substr(p, t);
229 p = t; 230 p = t;
230 t = strchr(t, '>') + 1; 231 t = strchr(t, '>') + 1;
231 ret->committer_email = substr(p, t); 232 ret->committer_email = substr(p, t);
232 ret->committer_date = atol(++t); 233 ret->committer_date = atol(++t);
233 p = strchr(t, '\n') + 1; 234 p = strchr(t, '\n') + 1;
234 } 235 }
235 236
237 if (!strncmp(p, "encoding ", 9)) {
238 p += 9;
239 t = strchr(p, '\n') + 1;
240 ret->msg_encoding = substr(p, t);
241 p = t;
242 } else
243 ret->msg_encoding = xstrdup(PAGE_ENCODING);
244
236 while (*p && (*p != '\n')) 245 while (*p && (*p != '\n'))
237 p = strchr(p, '\n') + 1; // skip unknown header fields 246 p = strchr(p, '\n') + 1; // skip unknown header fields
238 247
239 while (*p == '\n') 248 while (*p == '\n')
240 p = strchr(p, '\n') + 1; 249 p = strchr(p, '\n') + 1;
241 250
242 t = strchr(p, '\n'); 251 t = strchr(p, '\n');
243 if (t) { 252 if (t) {
@@ -248,16 +257,32 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
248 p = t + 1; 257 p = t + 1;
249 258
250 while (*p == '\n') 259 while (*p == '\n')
251 p = strchr(p, '\n') + 1; 260 p = strchr(p, '\n') + 1;
252 ret->msg = xstrdup(p); 261 ret->msg = xstrdup(p);
253 } else 262 } else
254 ret->subject = substr(p, p+strlen(p)); 263 ret->subject = substr(p, p+strlen(p));
255 264
265 if(strcmp(ret->msg_encoding, PAGE_ENCODING)) {
266 t = reencode_string(ret->subject, PAGE_ENCODING,
267 ret->msg_encoding);
268 if(t) {
269 free(ret->subject);
270 ret->subject = t;
271 }
272
273 t = reencode_string(ret->msg, PAGE_ENCODING,
274 ret->msg_encoding);
275 if(t) {
276 free(ret->msg);
277 ret->msg = t;
278 }
279 }
280
256 return ret; 281 return ret;
257} 282}
258 283
259 284
260struct taginfo *cgit_parse_tag(struct tag *tag) 285struct taginfo *cgit_parse_tag(struct tag *tag)
261{ 286{
262 void *data; 287 void *data;
263 enum object_type type; 288 enum object_type type;
diff --git a/shared.c b/shared.c
index 6117f5c..8cb4808 100644
--- a/shared.c
+++ b/shared.c
@@ -262,16 +262,18 @@ void cgit_querystring_cb(const char *name, const char *value)
262 262
263void *cgit_free_commitinfo(struct commitinfo *info) 263void *cgit_free_commitinfo(struct commitinfo *info)
264{ 264{
265 free(info->author); 265 free(info->author);
266 free(info->author_email); 266 free(info->author_email);
267 free(info->committer); 267 free(info->committer);
268 free(info->committer_email); 268 free(info->committer_email);
269 free(info->subject); 269 free(info->subject);
270 free(info->msg);
271 free(info->msg_encoding);
270 free(info); 272 free(info);
271 return NULL; 273 return NULL;
272} 274}
273 275
274int hextoint(char c) 276int hextoint(char c)
275{ 277{
276 if (c >= 'a' && c <= 'f') 278 if (c >= 'a' && c <= 'f')
277 return 10 + c - 'a'; 279 return 10 + c - 'a';
diff --git a/ui-log.c b/ui-log.c
index 9f5fdf6..e5f3c57 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -3,22 +3,28 @@
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 "cgit.h" 9#include "cgit.h"
10 10
11int files, lines; 11int files, add_lines, rem_lines;
12 12
13void count_lines(char *line, int size) 13void count_lines(char *line, int size)
14{ 14{
15 if (size>0 && (line[0] == '+' || line[0] == '-')) 15 if (size <= 0)
16 lines++; 16 return;
17
18 if (line[0] == '+')
19 add_lines++;
20
21 else if (line[0] == '-')
22 rem_lines++;
17} 23}
18 24
19void inspect_files(struct diff_filepair *pair) 25void inspect_files(struct diff_filepair *pair)
20{ 26{
21 files++; 27 files++;
22 if (cgit_repo->enable_log_linecount) 28 if (cgit_repo->enable_log_linecount)
23 cgit_diff_files(pair->one->sha1, pair->two->sha1, count_lines); 29 cgit_diff_files(pair->one->sha1, pair->two->sha1, count_lines);
24} 30}
@@ -30,23 +36,24 @@ void print_commit(struct commit *commit)
30 info = cgit_parse_commit(commit); 36 info = cgit_parse_commit(commit);
31 html("<tr><td>"); 37 html("<tr><td>");
32 cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); 38 cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE);
33 html("</td><td>"); 39 html("</td><td>");
34 cgit_commit_link(info->subject, NULL, NULL, cgit_query_head, 40 cgit_commit_link(info->subject, NULL, NULL, cgit_query_head,
35 sha1_to_hex(commit->object.sha1)); 41 sha1_to_hex(commit->object.sha1));
36 if (cgit_repo->enable_log_filecount) { 42 if (cgit_repo->enable_log_filecount) {
37 files = 0; 43 files = 0;
38 lines = 0; 44 add_lines = 0;
45 rem_lines = 0;
39 cgit_diff_commit(commit, inspect_files); 46 cgit_diff_commit(commit, inspect_files);
40 html("</td><td class='right'>"); 47 html("</td><td class='right'>");
41 htmlf("%d", files); 48 htmlf("%d", files);
42 if (cgit_repo->enable_log_linecount) { 49 if (cgit_repo->enable_log_linecount) {
43 html("</td><td class='right'>"); 50 html("</td><td class='right'>");
44 htmlf("%d", lines); 51 htmlf("-%d/+%d", rem_lines, add_lines);
45 } 52 }
46 } 53 }
47 html("</td><td>"); 54 html("</td><td>");
48 html_txt(info->author); 55 html_txt(info->author);
49 html("</td></tr>\n"); 56 html("</td></tr>\n");
50 cgit_free_commitinfo(info); 57 cgit_free_commitinfo(info);
51} 58}
52 59
@@ -83,19 +90,19 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
83 } 90 }
84 prepare_revision_walk(&rev); 91 prepare_revision_walk(&rev);
85 92
86 html("<table class='list nowrap'>"); 93 html("<table class='list nowrap'>");
87 html("<tr class='nohover'><th class='left'>Age</th>" 94 html("<tr class='nohover'><th class='left'>Age</th>"
88 "<th class='left'>Message</th>"); 95 "<th class='left'>Message</th>");
89 96
90 if (cgit_repo->enable_log_filecount) { 97 if (cgit_repo->enable_log_filecount) {
91 html("<th class='left'>Files</th>"); 98 html("<th class='right'>Files</th>");
92 if (cgit_repo->enable_log_linecount) 99 if (cgit_repo->enable_log_linecount)
93 html("<th class='left'>Lines</th>"); 100 html("<th class='right'>Lines</th>");
94 } 101 }
95 html("<th class='left'>Author</th></tr>\n"); 102 html("<th class='left'>Author</th></tr>\n");
96 103
97 if (ofs<0) 104 if (ofs<0)
98 ofs = 0; 105 ofs = 0;
99 106
100 for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) { 107 for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) {
101 free(commit->buffer); 108 free(commit->buffer);
diff --git a/ui-shared.c b/ui-shared.c
index 72a7b44..7c69f60 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -347,17 +347,17 @@ void cgit_print_age(time_t t, time_t max_relative, char *format)
347 return; 347 return;
348 } 348 }
349 htmlf("<span class='age-years'>%.0f years</span>", 349 htmlf("<span class='age-years'>%.0f years</span>",
350 secs * 1.0 / TM_YEAR); 350 secs * 1.0 / TM_YEAR);
351} 351}
352 352
353void cgit_print_docstart(char *title, struct cacheitem *item) 353void cgit_print_docstart(char *title, struct cacheitem *item)
354{ 354{
355 html("Content-Type: text/html; charset=utf-8\n"); 355 html("Content-Type: text/html; charset=" PAGE_ENCODING "\n");
356 htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); 356 htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime));
357 htmlf("Expires: %s\n", http_date(item->st.st_mtime + 357 htmlf("Expires: %s\n", http_date(item->st.st_mtime +
358 ttl_seconds(item->ttl))); 358 ttl_seconds(item->ttl)));
359 html("\n"); 359 html("\n");
360 html(cgit_doctype); 360 html(cgit_doctype);
361 html("<html>\n"); 361 html("<html>\n");
362 html("<head>\n"); 362 html("<head>\n");
363 html("<title>"); 363 html("<title>");