[csw-devel] SF.net SVN: gar:[6882] csw/mgar/pkg/cgit/trunk
trygvis at users.sourceforge.net
trygvis at users.sourceforge.net
Sun Oct 18 11:31:23 CEST 2009
Revision: 6882
http://gar.svn.sourceforge.net/gar/?rev=6882&view=rev
Author: trygvis
Date: 2009-10-18 09:31:17 +0000 (Sun, 18 Oct 2009)
Log Message:
-----------
o Adding a patch to the latest wip branch.
Modified Paths:
--------------
csw/mgar/pkg/cgit/trunk/Makefile
csw/mgar/pkg/cgit/trunk/checksums
Added Paths:
-----------
csw/mgar/pkg/cgit/trunk/files/8071e18dcbf56b98ecea4332e85884cdd91236cc-d8eb68d5d487014a16b680e7d52122d3415303da.diff
Modified: csw/mgar/pkg/cgit/trunk/Makefile
===================================================================
--- csw/mgar/pkg/cgit/trunk/Makefile 2009-10-18 09:28:04 UTC (rev 6881)
+++ csw/mgar/pkg/cgit/trunk/Makefile 2009-10-18 09:31:17 UTC (rev 6882)
@@ -1,5 +1,5 @@
GARNAME = cgit
-GARVERSION = 0.8.3-opencsw-1
+GARVERSION = 0.8.3_opencsw_1
CATEGORIES = devel
DESCRIPTION = Web front-end for Git
@@ -38,7 +38,8 @@
# uncomment the next line. Otherwise it is set by default to the value of MASTER_SITES
# UPSTREAM_MASTER_SITES =
-PATCHFILES = 0001-cgit.conf
+PATCHFILES = 0001-cgit.conf
+PATCHFILES += 8071e18dcbf56b98ecea4332e85884cdd91236cc-d8eb68d5d487014a16b680e7d52122d3415303da.diff
CONFIGURE_SCRIPTS =
Modified: csw/mgar/pkg/cgit/trunk/checksums
===================================================================
--- csw/mgar/pkg/cgit/trunk/checksums 2009-10-18 09:28:04 UTC (rev 6881)
+++ csw/mgar/pkg/cgit/trunk/checksums 2009-10-18 09:31:17 UTC (rev 6882)
@@ -1,3 +1,4 @@
-b013ec63820f1841df1cddaa35d66ed3 download/0001-cgit.conf
-27ef98eeb9066a301e60def5b6895a2c download/apache.conf.CSW
-03d013bbfdad0143ddcb4c29acf1b637 download/cgitrc.CSW
+b013ec63820f1841df1cddaa35d66ed3 0001-cgit.conf
+ab2c07418eec63118a2da512a99d7e34 8071e18dcbf56b98ecea4332e85884cdd91236cc-d8eb68d5d487014a16b680e7d52122d3415303da.diff
+27ef98eeb9066a301e60def5b6895a2c apache.conf.CSW
+03d013bbfdad0143ddcb4c29acf1b637 cgitrc.CSW
Added: csw/mgar/pkg/cgit/trunk/files/8071e18dcbf56b98ecea4332e85884cdd91236cc-d8eb68d5d487014a16b680e7d52122d3415303da.diff
===================================================================
--- csw/mgar/pkg/cgit/trunk/files/8071e18dcbf56b98ecea4332e85884cdd91236cc-d8eb68d5d487014a16b680e7d52122d3415303da.diff (rev 0)
+++ csw/mgar/pkg/cgit/trunk/files/8071e18dcbf56b98ecea4332e85884cdd91236cc-d8eb68d5d487014a16b680e7d52122d3415303da.diff 2009-10-18 09:31:17 UTC (rev 6882)
@@ -0,0 +1,887 @@
+diff --git a/Makefile b/Makefile
+index 60d8c58..cb7875e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -90,6 +90,7 @@ OBJECTS += ui-refs.o
+ OBJECTS += ui-repolist.o
+ OBJECTS += ui-shared.o
+ OBJECTS += ui-snapshot.o
++OBJECTS += ui-ssdiff.o
+ OBJECTS += ui-stats.o
+ OBJECTS += ui-summary.o
+ OBJECTS += ui-tag.o
+diff --git a/cgit.c b/cgit.c
+index bd37788..84f44ba 100644
+--- a/cgit.c
++++ b/cgit.c
+@@ -182,6 +182,8 @@ void config_cb(const char *name, const char *value)
+ ctx.cfg.summary_branches = atoi(value);
+ else if (!strcmp(name, "summary-tags"))
+ ctx.cfg.summary_tags = atoi(value);
++ else if (!strcmp(name, "side-by-side-diffs"))
++ ctx.cfg.ssdiff = atoi(value);
+ else if (!strcmp(name, "agefile"))
+ ctx.cfg.agefile = xstrdup(value);
+ else if (!strcmp(name, "renamelimit"))
+@@ -209,6 +211,8 @@ static void querystring_cb(const char *name, const char *value)
+ } else if (!strcmp(name, "p")) {
+ ctx.qry.page = xstrdup(value);
+ } else if (!strcmp(name, "url")) {
++ if (*value == '/')
++ value++;
+ ctx.qry.url = xstrdup(value);
+ cgit_parse_url(value);
+ } else if (!strcmp(name, "qt")) {
+@@ -238,6 +242,8 @@ static void querystring_cb(const char *name, const char *value)
+ ctx.qry.showmsg = atoi(value);
+ } else if (!strcmp(name, "period")) {
+ ctx.qry.period = xstrdup(value);
++ } else if (!strcmp(name, "ss")) {
++ ctx.qry.ssdiff = atoi(value);
+ }
+ }
+
+@@ -279,6 +285,7 @@ static void prepare_context(struct cgit_context *ctx)
+ ctx->cfg.summary_branches = 10;
+ ctx->cfg.summary_log = 10;
+ ctx->cfg.summary_tags = 10;
++ ctx->cfg.ssdiff = 0;
+ ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG"));
+ ctx->env.http_host = xstrdupn(getenv("HTTP_HOST"));
+ ctx->env.https = xstrdupn(getenv("HTTPS"));
+diff --git a/cgit.css b/cgit.css
+index c47ebc9..3f37165 100644
+--- a/cgit.css
++++ b/cgit.css
+@@ -601,3 +601,92 @@ table.hgraph div.bar {
+ background-color: #eee;
+ height: 1em;
+ }
++
++table.ssdiff {
++ width: 100%;
++}
++
++table.ssdiff td {
++ font-size: 75%;
++ font-family: monospace;
++ white-space: pre;
++ padding: 1px 4px 1px 4px;
++ border-left: solid 1px #aaa;
++ border-right: solid 1px #aaa;
++}
++
++table.ssdiff td.add {
++ color: black;
++ background: #cfc;
++ min-width: 50%;
++}
++
++table.ssdiff td.add_dark {
++ color: black;
++ background: #aca;
++ min-width: 50%;
++}
++
++table.ssdiff td.del {
++ color: black;
++ background: #fcc;
++ min-width: 50%;
++}
++
++table.ssdiff td.del_dark {
++ color: black;
++ background: #caa;
++ min-width: 50%;
++}
++
++table.ssdiff td.changed {
++ color: black;
++ background: #ffc;
++ min-width: 50%;
++}
++
++table.ssdiff td.changed_dark {
++ color: black;
++ background: #cca;
++ min-width: 50%;
++}
++
++table.ssdiff td.lineno {
++ color: black;
++ background: #eee;
++ text-align: right;
++ width: 3em;
++ min-width: 3em;
++}
++
++table.ssdiff td.hunk {
++ color: #black;
++ background: #ccf;
++ border-top: solid 1px #aaa;
++ border-bottom: solid 1px #aaa;
++}
++
++table.ssdiff td.head {
++ border-top: solid 1px #aaa;
++ border-bottom: solid 1px #aaa;
++}
++
++table.ssdiff td.head div.head {
++ font-weight: bold;
++ color: black;
++}
++
++table.ssdiff td.foot {
++ border-top: solid 1px #aaa;
++ border-left: none;
++ border-right: none;
++ border-bottom: none;
++}
++
++table.ssdiff td.space {
++ border: none;
++}
++
++table.ssdiff td.space div {
++ min-height: 3em;
++}
+\ No newline at end of file
+diff --git a/cgit.h b/cgit.h
+index 6c6c460..b7b0adb 100644
+--- a/cgit.h
++++ b/cgit.h
+@@ -143,6 +143,7 @@ struct cgit_query {
+ int nohead;
+ char *sort;
+ int showmsg;
++ int ssdiff;
+ };
+
+ struct cgit_config {
+@@ -194,6 +195,7 @@ struct cgit_config {
+ int summary_branches;
+ int summary_log;
+ int summary_tags;
++ int ssdiff;
+ struct string_list mimetypes;
+ struct cgit_filter *about_filter;
+ struct cgit_filter *commit_filter;
+diff --git a/cgitrc.5.txt b/cgitrc.5.txt
+index 0c13485..d0fd9a1 100644
+--- a/cgitrc.5.txt
++++ b/cgitrc.5.txt
+@@ -241,6 +241,10 @@ section::
+ after this option will inherit the current section name. Default value:
+ none.
+
++side-by-side-diffs::
++ If set to "1" shows side-by-side diffs instead of unidiffs per
++ default. Default value: "0".
++
+ snapshots::
+ Text which specifies the default set of snapshot formats generated by
+ cgit. The value is a space-separated list of zero or more of the
+diff --git a/ui-commit.c b/ui-commit.c
+index f5b0ae5..b5e3c01 100644
+--- a/ui-commit.c
++++ b/ui-commit.c
+@@ -58,9 +58,14 @@ void cgit_print_commit(char *hex)
+ html("</td></tr>\n");
+ html("<tr><th>commit</th><td colspan='2' class='sha1'>");
+ tmp = sha1_to_hex(commit->object.sha1);
+- cgit_commit_link(tmp, NULL, NULL, ctx.qry.head, tmp);
++ cgit_commit_link(tmp, NULL, NULL, ctx.qry.head, tmp, 0);
+ html(" (");
+ cgit_patch_link("patch", NULL, NULL, NULL, tmp);
++ html(") (");
++ if ((ctx.qry.ssdiff && !ctx.cfg.ssdiff) || (!ctx.qry.ssdiff && ctx.cfg.ssdiff))
++ cgit_commit_link("unidiff", NULL, NULL, ctx.qry.head, tmp, 1);
++ else
++ cgit_commit_link("side-by-side diff", NULL, NULL, ctx.qry.head, tmp, 1);
+ html(")</td></tr>\n");
+ html("<tr><th>tree</th><td colspan='2' class='sha1'>");
+ tmp = xstrdup(hex);
+@@ -78,10 +83,10 @@ void cgit_print_commit(char *hex)
+ html("<tr><th>parent</th>"
+ "<td colspan='2' class='sha1'>");
+ cgit_commit_link(sha1_to_hex(p->item->object.sha1), NULL, NULL,
+- ctx.qry.head, sha1_to_hex(p->item->object.sha1));
++ ctx.qry.head, sha1_to_hex(p->item->object.sha1), 0);
+ html(" (");
+ cgit_diff_link("diff", NULL, NULL, ctx.qry.head, hex,
+- sha1_to_hex(p->item->object.sha1), NULL);
++ sha1_to_hex(p->item->object.sha1), NULL, 0);
+ html(")</td></tr>");
+ parents++;
+ }
+diff --git a/ui-diff.c b/ui-diff.c
+index 2196745..a92a768 100644
+--- a/ui-diff.c
++++ b/ui-diff.c
+@@ -9,6 +9,7 @@
+ #include "cgit.h"
+ #include "html.h"
+ #include "ui-shared.h"
++#include "ui-ssdiff.h"
+
+ unsigned char old_rev_sha1[20];
+ unsigned char new_rev_sha1[20];
+@@ -32,6 +33,7 @@ static struct fileinfo {
+ int binary:1;
+ } *items;
+
++static int use_ssdiff = 0;
+
+ static void print_fileinfo(struct fileinfo *info)
+ {
+@@ -83,7 +85,7 @@ static void print_fileinfo(struct fileinfo *info)
+ }
+ htmlf("</td><td class='%s'>", class);
+ cgit_diff_link(info->new_path, NULL, NULL, ctx.qry.head, ctx.qry.sha1,
+- ctx.qry.sha2, info->new_path);
++ ctx.qry.sha2, info->new_path, 0);
+ if (info->status == DIFF_STATUS_COPIED || info->status == DIFF_STATUS_RENAMED)
+ htmlf(" (%s from %s)",
+ info->status == DIFF_STATUS_COPIED ? "copied" : "renamed",
+@@ -158,7 +160,7 @@ void cgit_print_diffstat(const unsigned char *old_sha1,
+
+ html("<div class='diffstat-header'>");
+ cgit_diff_link("Diffstat", NULL, NULL, ctx.qry.head, ctx.qry.sha1,
+- ctx.qry.sha2, NULL);
++ ctx.qry.sha2, NULL, 0);
+ html("</div>");
+ html("<table summary='diffstat' class='diffstat'>");
+ max_changes = 0;
+@@ -246,26 +248,54 @@ static void header(unsigned char *sha1, char *path1, int mode1,
+ html("</div>");
+ }
+
++static void print_ssdiff_link()
++{
++ if (!strcmp(ctx.qry.page, "diff")) {
++ if (use_ssdiff)
++ cgit_diff_link("Unidiff", NULL, NULL, ctx.qry.head,
++ ctx.qry.sha1, ctx.qry.sha2, ctx.qry.path, 1);
++ else
++ cgit_diff_link("Side-by-side diff", NULL, NULL,
++ ctx.qry.head, ctx.qry.sha1,
++ ctx.qry.sha2, ctx.qry.path, 1);
++ }
++}
++
+ static void filepair_cb(struct diff_filepair *pair)
+ {
+ unsigned long old_size = 0;
+ unsigned long new_size = 0;
+ int binary = 0;
++ linediff_fn print_line_fn = print_line;
+
++ if (use_ssdiff) {
++ cgit_ssdiff_header_begin();
++ print_line_fn = cgit_ssdiff_line_cb;
++ }
+ header(pair->one->sha1, pair->one->path, pair->one->mode,
+ pair->two->sha1, pair->two->path, pair->two->mode);
++ if (use_ssdiff)
++ cgit_ssdiff_header_end();
+ if (S_ISGITLINK(pair->one->mode) || S_ISGITLINK(pair->two->mode)) {
+ if (S_ISGITLINK(pair->one->mode))
+- print_line(fmt("-Subproject %s", sha1_to_hex(pair->one->sha1)), 52);
++ print_line_fn(fmt("-Subproject %s", sha1_to_hex(pair->one->sha1)), 52);
+ if (S_ISGITLINK(pair->two->mode))
+- print_line(fmt("+Subproject %s", sha1_to_hex(pair->two->sha1)), 52);
++ print_line_fn(fmt("+Subproject %s", sha1_to_hex(pair->two->sha1)), 52);
++ if (use_ssdiff)
++ cgit_ssdiff_footer();
+ return;
+ }
+- if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
+- &new_size, &binary, print_line))
++ if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
++ &new_size, &binary, print_line_fn))
+ cgit_print_error("Error running diff");
+- if (binary)
+- html("Binary files differ");
++ if (binary) {
++ if (use_ssdiff)
++ html("<tr><td colspan='4'>Binary files differ</td></tr>");
++ else
++ html("Binary files differ");
++ }
++ if (use_ssdiff)
++ cgit_ssdiff_footer();
+ }
+
+ void cgit_print_diff(const char *new_rev, const char *old_rev, const char *prefix)
+@@ -303,11 +333,21 @@ void cgit_print_diff(const char *new_rev, const char *old_rev, const char *prefi
+ if (!commit2 || parse_commit(commit2))
+ cgit_print_error(fmt("Bad commit: %s", sha1_to_hex(old_rev_sha1)));
+ }
++
++ if ((ctx.qry.ssdiff && !ctx.cfg.ssdiff) || (!ctx.qry.ssdiff && ctx.cfg.ssdiff))
++ use_ssdiff = 1;
++
++ print_ssdiff_link();
+ cgit_print_diffstat(old_rev_sha1, new_rev_sha1);
+
+- html("<table summary='diff' class='diff'>");
+- html("<tr><td>");
++ if (use_ssdiff) {
++ html("<table summary='ssdiff' class='ssdiff'>");
++ } else {
++ html("<table summary='diff' class='diff'>");
++ html("<tr><td>");
++ }
+ cgit_diff_tree(old_rev_sha1, new_rev_sha1, filepair_cb, prefix);
+- html("</td></tr>");
++ if (!use_ssdiff)
++ html("</td></tr>");
+ html("</table>");
+ }
+diff --git a/ui-log.c b/ui-log.c
+index f3132c9..0947604 100644
+--- a/ui-log.c
++++ b/ui-log.c
+@@ -66,7 +66,7 @@ void show_commit_decorations(struct commit *commit)
+ else {
+ strncpy(buf, deco->name, sizeof(buf) - 1);
+ cgit_commit_link(buf, NULL, "deco", ctx.qry.head,
+- sha1_to_hex(commit->object.sha1));
++ sha1_to_hex(commit->object.sha1), 0);
+ }
+ deco = deco->next;
+ }
+@@ -89,7 +89,7 @@ void print_commit(struct commit *commit)
+ htmlf("</td><td%s>",
+ ctx.qry.showmsg ? " class='logsubject'" : "");
+ cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head,
+- sha1_to_hex(commit->object.sha1));
++ sha1_to_hex(commit->object.sha1), 0);
+ show_commit_decorations(commit);
+ html("</td><td>");
+ html_txt(info->author);
+diff --git a/ui-refs.c b/ui-refs.c
+index d3b4f6e..33d9bec 100644
+--- a/ui-refs.c
++++ b/ui-refs.c
+@@ -74,7 +74,7 @@ static int print_branch(struct refinfo *ref)
+ html("</td><td>");
+
+ if (ref->object->type == OBJ_COMMIT) {
+- cgit_commit_link(info->subject, NULL, NULL, name, NULL);
++ cgit_commit_link(info->subject, NULL, NULL, name, NULL, 0);
+ html("</td><td>");
+ html_txt(info->author);
+ html("</td><td colspan='2'>");
+diff --git a/ui-repolist.c b/ui-repolist.c
+index 3ef2e99..0a0b6ca 100644
+--- a/ui-repolist.c
++++ b/ui-repolist.c
+@@ -94,7 +94,7 @@ int is_in_url(struct cgit_repo *repo)
+
+ void print_sort_header(const char *title, const char *sort)
+ {
+- htmlf("<th class='left'><a href='./?s=%s", sort);
++ htmlf("<th class='left'><a href='%s?s=%s", cgit_rooturl(), sort);
+ if (ctx.qry.search) {
+ html("&q=");
+ html_url_arg(ctx.qry.search);
+diff --git a/ui-shared.c b/ui-shared.c
+index 07d5dd4..48c2395 100644
+--- a/ui-shared.c
++++ b/ui-shared.c
+@@ -317,7 +317,7 @@ void cgit_log_link(char *name, char *title, char *class, char *head,
+ }
+
+ void cgit_commit_link(char *name, char *title, char *class, char *head,
+- char *rev)
++ char *rev, int toggle_ssdiff)
+ {
+ if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) {
+ name[ctx.cfg.max_msg_len] = '\0';
+@@ -325,7 +325,23 @@ void cgit_commit_link(char *name, char *title, char *class, char *head,
+ name[ctx.cfg.max_msg_len - 2] = '.';
+ name[ctx.cfg.max_msg_len - 3] = '.';
+ }
+- reporevlink("commit", name, title, class, head, rev, NULL);
++
++ char *delim;
++
++ delim = repolink(title, class, "commit", head, NULL);
++ if (rev && strcmp(rev, ctx.qry.head)) {
++ html(delim);
++ html("id=");
++ html_url_arg(rev);
++ delim = "&";
++ }
++ if ((ctx.qry.ssdiff && !toggle_ssdiff) || (!ctx.qry.ssdiff && toggle_ssdiff)) {
++ html(delim);
++ html("ss=1");
++ }
++ html("'>");
++ html_txt(name);
++ html("</a>");
+ }
+
+ void cgit_refs_link(char *name, char *title, char *class, char *head,
+@@ -341,7 +357,8 @@ void cgit_snapshot_link(char *name, char *title, char *class, char *head,
+ }
+
+ void cgit_diff_link(char *name, char *title, char *class, char *head,
+- char *new_rev, char *old_rev, char *path)
++ char *new_rev, char *old_rev, char *path,
++ int toggle_ssdiff)
+ {
+ char *delim;
+
+@@ -356,6 +373,11 @@ void cgit_diff_link(char *name, char *title, char *class, char *head,
+ html(delim);
+ html("id2=");
+ html_url_arg(old_rev);
++ delim = "&";
++ }
++ if ((ctx.qry.ssdiff && !toggle_ssdiff) || (!ctx.qry.ssdiff && toggle_ssdiff)) {
++ html(delim);
++ html("ss=1");
+ }
+ html("'>");
+ html_txt(name);
+@@ -383,7 +405,7 @@ void cgit_object_link(struct object *obj)
+ shortrev[10] = '\0';
+ if (obj->type == OBJ_COMMIT) {
+ cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL,
+- ctx.qry.head, fullrev);
++ ctx.qry.head, fullrev, 0);
+ return;
+ } else if (obj->type == OBJ_TREE)
+ page = "tree";
+@@ -695,9 +717,9 @@ void cgit_print_pageheader(struct cgit_context *ctx)
+ cgit_tree_link("tree", NULL, hc(cmd, "tree"), ctx->qry.head,
+ ctx->qry.sha1, NULL);
+ cgit_commit_link("commit", NULL, hc(cmd, "commit"),
+- ctx->qry.head, ctx->qry.sha1);
++ ctx->qry.head, ctx->qry.sha1, 0);
+ cgit_diff_link("diff", NULL, hc(cmd, "diff"), ctx->qry.head,
+- ctx->qry.sha1, ctx->qry.sha2, NULL);
++ ctx->qry.sha1, ctx->qry.sha2, NULL, 0);
+ if (ctx->repo->max_stats)
+ cgit_stats_link("stats", NULL, hc(cmd, "stats"),
+ ctx->qry.head, NULL);
+@@ -760,13 +782,18 @@ void cgit_print_snapshot_links(const char *repo, const char *head,
+ const char *hex, int snapshots)
+ {
+ const struct cgit_snapshot_format* f;
++ char *prefix;
+ char *filename;
++ unsigned char sha1[20];
+
++ if (get_sha1(fmt("refs/tags/%s", hex), sha1) == 0 &&
++ (hex[0] == 'v' || hex[0] == 'V') && isdigit(hex[1]))
++ hex++;
++ prefix = xstrdup(fmt("%s-%s", cgit_repobasename(repo), hex));
+ for (f = cgit_snapshot_formats; f->suffix; f++) {
+ if (!(snapshots & f->bit))
+ continue;
+- filename = fmt("%s-%s%s", cgit_repobasename(repo), hex,
+- f->suffix);
++ filename = fmt("%s%s", prefix, f->suffix);
+ cgit_snapshot_link(filename, NULL, NULL, NULL, NULL, filename);
+ html("<br/>");
+ }
+diff --git a/ui-shared.h b/ui-shared.h
+index bff4826..9ebc1f9 100644
+--- a/ui-shared.h
++++ b/ui-shared.h
+@@ -3,6 +3,7 @@
+
+ extern char *cgit_httpscheme();
+ extern char *cgit_hosturl();
++extern char *cgit_rooturl();
+ extern char *cgit_repourl(const char *reponame);
+ extern char *cgit_fileurl(const char *reponame, const char *pagename,
+ const char *filename, const char *query);
+@@ -22,7 +23,7 @@ extern void cgit_log_link(char *name, char *title, char *class, char *head,
+ char *rev, char *path, int ofs, char *grep,
+ char *pattern, int showmsg);
+ extern void cgit_commit_link(char *name, char *title, char *class, char *head,
+- char *rev);
++ char *rev, int toggle_ssdiff);
+ extern void cgit_patch_link(char *name, char *title, char *class, char *head,
+ char *rev);
+ extern void cgit_refs_link(char *name, char *title, char *class, char *head,
+@@ -30,7 +31,8 @@ extern void cgit_refs_link(char *name, char *title, char *class, char *head,
+ extern void cgit_snapshot_link(char *name, char *title, char *class,
+ char *head, char *rev, char *archivename);
+ extern void cgit_diff_link(char *name, char *title, char *class, char *head,
+- char *new_rev, char *old_rev, char *path);
++ char *new_rev, char *old_rev, char *path,
++ int toggle_ssdiff);
+ extern void cgit_stats_link(char *name, char *title, char *class, char *head,
+ char *path);
+ extern void cgit_object_link(struct object *obj);
+diff --git a/ui-ssdiff.c b/ui-ssdiff.c
+new file mode 100644
+index 0000000..5673642
+--- /dev/null
++++ b/ui-ssdiff.c
+@@ -0,0 +1,274 @@
++#include "cgit.h"
++#include "html.h"
++#include "ui-shared.h"
++
++extern int use_ssdiff;
++
++static int current_old_line, current_new_line;
++
++struct deferred_lines {
++ int line_no;
++ char *line;
++ struct deferred_lines *next;
++};
++
++static struct deferred_lines *deferred_old, *deferred_old_last;
++static struct deferred_lines *deferred_new, *deferred_new_last;
++
++static int line_from_hunk(char *line, char type)
++{
++ char *buf1, *buf2;
++ int len;
++
++ buf1 = strchr(line, type);
++ if (buf1 == NULL)
++ return 0;
++ buf1 += 1;
++ buf2 = strchr(buf1, ',');
++ if (buf2 == NULL)
++ return 0;
++ len = buf2 - buf1;
++ buf2 = xmalloc(len + 1);
++ strncpy(buf2, buf1, len);
++ buf2[len] = '\0';
++ int res = atoi(buf2);
++ free(buf2);
++ return res;
++}
++
++static char *replace_tabs(char *line)
++{
++ char *prev_buf = line;
++ char *cur_buf;
++ int linelen = strlen(line);
++ int n_tabs = 0;
++ int i;
++ char *result;
++ char *spaces = " ";
++
++ if (linelen == 0) {
++ result = xmalloc(1);
++ result[0] = '\0';
++ return result;
++ }
++
++ for (i = 0; i < linelen; i++)
++ if (line[i] == '\t')
++ n_tabs += 1;
++ result = xmalloc(linelen + n_tabs * 8 + 1);
++ result[0] = '\0';
++
++ while (1) {
++ cur_buf = strchr(prev_buf, '\t');
++ if (!cur_buf) {
++ strcat(result, prev_buf);
++ break;
++ } else {
++ strcat(result, " ");
++ strncat(result, spaces, 8 - (strlen(result) % 8));
++ strncat(result, prev_buf, cur_buf - prev_buf);
++ }
++ prev_buf = cur_buf + 1;
++ }
++ return result;
++}
++
++static void deferred_old_add(char *line, int line_no)
++{
++ struct deferred_lines *item = xmalloc(sizeof(struct deferred_lines));
++ item->line = xstrdup(line);
++ item->line_no = line_no;
++ item->next = NULL;
++ if (deferred_old) {
++ deferred_old_last->next = item;
++ deferred_old_last = item;
++ } else {
++ deferred_old = deferred_old_last = item;
++ }
++}
++
++static void deferred_new_add(char *line, int line_no)
++{
++ struct deferred_lines *item = xmalloc(sizeof(struct deferred_lines));
++ item->line = xstrdup(line);
++ item->line_no = line_no;
++ item->next = NULL;
++ if (deferred_new) {
++ deferred_new_last->next = item;
++ deferred_new_last = item;
++ } else {
++ deferred_new = deferred_new_last = item;
++ }
++}
++
++static void print_ssdiff_line(char *class, int old_line_no, char *old_line,
++ int new_line_no, char *new_line)
++{
++ html("<tr>");
++ if (old_line_no > 0)
++ htmlf("<td class='lineno'>%d</td><td class='%s'>",
++ old_line_no, class);
++ else if (old_line)
++ htmlf("<td class='lineno'></td><td class='%s'>", class);
++ else
++ htmlf("<td class='lineno'></td><td class='%s_dark'>", class);
++
++ if (old_line) {
++ old_line = replace_tabs(old_line + 1);
++ html_txt(old_line);
++ free(old_line);
++ }
++
++ html("</td>");
++
++ if (new_line_no > 0)
++ htmlf("<td class='lineno'>%d</td><td class='%s'>",
++ new_line_no, class);
++ else if (new_line)
++ htmlf("<td class='lineno'></td><td class='%s'>", class);
++ else
++ htmlf("<td class='lineno'></td><td class='%s_dark'>", class);
++
++ if (new_line) {
++ new_line = replace_tabs(new_line + 1);
++ html_txt(new_line);
++ free(new_line);
++ }
++
++ html("</td></tr>");
++}
++
++static void print_deferred_old_lines()
++{
++ struct deferred_lines *iter_old, *tmp;
++
++ iter_old = deferred_old;
++ while (iter_old) {
++ print_ssdiff_line("del", iter_old->line_no,
++ iter_old->line, -1, NULL);
++ tmp = iter_old->next;
++ free(iter_old);
++ iter_old = tmp;
++ }
++}
++
++static void print_deferred_new_lines()
++{
++ struct deferred_lines *iter_new, *tmp;
++
++ iter_new = deferred_new;
++ while (iter_new) {
++ print_ssdiff_line("add", -1, NULL, iter_new->line_no,
++ iter_new->line);
++ tmp = iter_new->next;
++ free(iter_new);
++ iter_new = tmp;
++ }
++}
++
++static void print_deferred_changed_lines()
++{
++ struct deferred_lines *iter_old, *iter_new, *tmp;
++
++ iter_old = deferred_old;
++ iter_new = deferred_new;
++ while (iter_old || iter_new) {
++ if (iter_old && iter_new)
++ print_ssdiff_line("changed", iter_old->line_no,
++ iter_old->line,
++ iter_new->line_no, iter_new->line);
++ else if (iter_old)
++ print_ssdiff_line("changed", iter_old->line_no,
++ iter_old->line, -1, NULL);
++ else if (iter_new)
++ print_ssdiff_line("changed", -1, NULL,
++ iter_new->line_no, iter_new->line);
++
++ if (iter_old) {
++ tmp = iter_old->next;
++ free(iter_old);
++ iter_old = tmp;
++ }
++
++ if (iter_new) {
++ tmp = iter_new->next;
++ free(iter_new);
++ iter_new = tmp;
++ }
++ }
++}
++
++void cgit_ssdiff_print_deferred_lines()
++{
++ if (!deferred_old && !deferred_new)
++ return;
++
++ if (deferred_old && !deferred_new)
++ print_deferred_old_lines();
++ else if (!deferred_old && deferred_new)
++ print_deferred_new_lines();
++ else
++ print_deferred_changed_lines();
++
++ deferred_old = deferred_old_last = NULL;
++ deferred_new = deferred_new_last = NULL;
++}
++
++/*
++ * print a single line returned from xdiff
++ */
++void cgit_ssdiff_line_cb(char *line, int len)
++{
++ char c = line[len - 1];
++
++ line[len - 1] = '\0';
++
++ if (line[0] == '@') {
++ current_old_line = line_from_hunk(line, '-');
++ current_new_line = line_from_hunk(line, '+');
++ }
++
++ if (line[0] == ' ') {
++ if (deferred_old || deferred_new)
++ cgit_ssdiff_print_deferred_lines();
++ print_ssdiff_line("ctx", current_old_line, line,
++ current_new_line, line);
++ current_old_line += 1;
++ current_new_line += 1;
++ } else if (line[0] == '+') {
++ deferred_new_add(line, current_new_line);
++ current_new_line += 1;
++ } else if (line[0] == '-') {
++ deferred_old_add(line, current_old_line);
++ current_old_line += 1;
++ } else if (line[0] == '@') {
++ html("<tr><td colspan='4' class='hunk'>");
++ html_txt(line);
++ html("</td></tr>");
++ } else {
++ html("<tr><td colspan='4' class='ctx'>");
++ html_txt(line);
++ html("</td></tr>");
++ }
++ line[len - 1] = c;
++}
++
++void cgit_ssdiff_header_begin()
++{
++ current_old_line = -1;
++ current_new_line = -1;
++ html("<tr><td class='space' colspan='4'><div></div></td></tr>");
++ html("<tr><td class='head' colspan='4'>");
++}
++
++void cgit_ssdiff_header_end()
++{
++ html("</td><tr>");
++}
++
++void cgit_ssdiff_footer()
++{
++ if (deferred_old || deferred_new)
++ cgit_ssdiff_print_deferred_lines();
++ html("<tr><td class='foot' colspan='4'></td></tr>");
++}
+diff --git a/ui-ssdiff.h b/ui-ssdiff.h
+new file mode 100644
+index 0000000..64b4b12
+--- /dev/null
++++ b/ui-ssdiff.h
+@@ -0,0 +1,13 @@
++#ifndef UI_SSDIFF_H
++#define UI_SSDIFF_H
++
++extern void cgit_ssdiff_print_deferred_lines();
++
++extern void cgit_ssdiff_line_cb(char *line, int len);
++
++extern void cgit_ssdiff_header_begin();
++extern void cgit_ssdiff_header_end();
++
++extern void cgit_ssdiff_footer();
++
++#endif /* UI_SSDIFF_H */
+diff --git a/ui-tag.c b/ui-tag.c
+index c2d72af..39e4cb8 100644
+--- a/ui-tag.c
++++ b/ui-tag.c
+@@ -30,6 +30,14 @@ static void print_tag_content(char *buf)
+ }
+ }
+
++void print_download_links(char *revname)
++{
++ html("<tr><th>download</th><td class='sha1'>");
++ cgit_print_snapshot_links(ctx.qry.repo, ctx.qry.head,
++ revname, ctx.repo->snapshots);
++ html("</td></tr>");
++}
++
+ void cgit_print_tag(char *revname)
+ {
+ unsigned char sha1[20];
+@@ -56,16 +64,16 @@ void cgit_print_tag(char *revname)
+ return;
+ }
+ html("<table class='commit-info'>\n");
+- htmlf("<tr><td>Tag name</td><td>");
++ htmlf("<tr><td>tag name</td><td>");
+ html_txt(revname);
+ htmlf(" (%s)</td></tr>\n", sha1_to_hex(sha1));
+ if (info->tagger_date > 0) {
+- html("<tr><td>Tag date</td><td>");
++ html("<tr><td>tag date</td><td>");
+ cgit_print_date(info->tagger_date, FMT_LONGDATE, ctx.cfg.local_time);
+ html("</td></tr>\n");
+ }
+ if (info->tagger) {
+- html("<tr><td>Tagged by</td><td>");
++ html("<tr><td>tagged by</td><td>");
+ html_txt(info->tagger);
+ if (info->tagger_email && !ctx.cfg.noplainemail) {
+ html(" ");
+@@ -73,19 +81,23 @@ void cgit_print_tag(char *revname)
+ }
+ html("</td></tr>\n");
+ }
+- html("<tr><td>Tagged object</td><td>");
++ html("<tr><td>tagged object</td><td class='sha1'>");
+ cgit_object_link(tag->tagged);
+ html("</td></tr>\n");
++ if (ctx.repo->snapshots)
++ print_download_links(revname);
+ html("</table>\n");
+ print_tag_content(info->msg);
+ } else {
+ html("<table class='commit-info'>\n");
+- htmlf("<tr><td>Tag name</td><td>");
++ htmlf("<tr><td>tag name</td><td>");
+ html_txt(revname);
+ html("</td></tr>\n");
+- html("<tr><td>Tagged object</td><td>");
++ html("<tr><td>Tagged object</td><td class='sha1'>");
+ cgit_object_link(obj);
+ html("</td></tr>\n");
++ if (ctx.repo->snapshots)
++ print_download_links(revname);
+ html("</table>\n");
+ }
+ return;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the devel
mailing list