webrev revision 12969
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen#!/usr/perl5/bin/perl -w
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen#
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen# Script for generating code review pages similar to those generated by
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen# ON's webrev tool
5314b66fca6b2cf6b749d296a30a5eb039e0e9baTimo Sirainen#
5bda841ca9e2ddd90702dc7e2a15326e4068066eTimo Sirainen# CDDL HEADER START
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen# The contents of this file are subject to the terms of the
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen# Common Development and Distribution License, Version 1.0 only
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen# (the "License"). You may not use this file except in compliance
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen# with the License.
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen#
88b9f9eb91da632d3e941fe4276f8ace03205b25Timo Sirainen# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen# or http://www.opensolaris.org/os/licensing.
027c729b3107441f54a2602ccf2c67c6206998d5Timo Sirainen# See the License for the specific language governing permissions
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen# and limitations under the License.
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen#
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen# When distributing Covered Code, include this CDDL HEADER in each
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2ce5b1d19cba4654239116a34e3ad9d5b6af8551Timo Sirainen# If applicable, add the following below this CDDL HEADER, with the
2ce5b1d19cba4654239116a34e3ad9d5b6af8551Timo Sirainen# fields enclosed by brackets "[]" replaced with your own identifying
f90c6ff1ae3d5675abfc6ae05574924fda8dca9eTimo Sirainen# information: Portions Copyright [yyyy] [name of copyright owner]
f90c6ff1ae3d5675abfc6ae05574924fda8dca9eTimo Sirainen#
f90c6ff1ae3d5675abfc6ae05574924fda8dca9eTimo Sirainen# CDDL HEADER END
f90c6ff1ae3d5675abfc6ae05574924fda8dca9eTimo Sirainen#
2ce5b1d19cba4654239116a34e3ad9d5b6af8551Timo Sirainen#
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen# Use is subject to license terms.
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen# FIXMEs:
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen# - require the target dir to be empty
33502e55a9bf4cafcd184ca9b114c126e420f856Timo Sirainen# - breaks if you have a new subdir that is not under svn control
33502e55a9bf4cafcd184ca9b114c126e420f856Timo Sirainen# - should have a way to exclude some or all not-svn-controlled files
4ca9910d9db31a68d9d501150045cfd4bb1e2ac7Timo Sirainen
33502e55a9bf4cafcd184ca9b114c126e420f856Timo Sirainenuse strict;
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainenuse Fcntl;
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainenuse File::Basename;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen#
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen# Usage: webrev /path/to/output/dir
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen#
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen# creates the html report of changed in the current svn workspace (current dir)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen# FIXME: would be nice to turn these into command line options
bd49b2e35dfa08753e89bef12a694978599d0fc0Timo Sirainen# max number of chars in each line, above which lines are wrapped in
bd49b2e35dfa08753e89bef12a694978599d0fc0Timo Sirainen# side-by-side diffs
bd49b2e35dfa08753e89bef12a694978599d0fc0Timo Sirainenmy $SDIFF_MAX_LINE=80;
bd49b2e35dfa08753e89bef12a694978599d0fc0Timo Sirainen# number of lines of context in sdiffs
bd49b2e35dfa08753e89bef12a694978599d0fc0Timo Sirainenmy $SDIFF_CONTEXT=20;
bd49b2e35dfa08753e89bef12a694978599d0fc0Timo Sirainen
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen# Valid @FOO@ tags in the HTML templates:
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen#
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen# @TITLE@ - page title
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen# @AUTHOR@ - real name of the current user according to the passwd entry
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen# @COPYRIGHT@ - copyright statement (not implemented)
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen# @UNAME@ - current user name
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen# @HOSTNAME@ - hostname of the current host as printed by /bin/hostname
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen# @DATE@ - current date string as printed by /bin/date
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen#
88b9f9eb91da632d3e941fe4276f8ace03205b25Timo Sirainen
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen# HTML page header template for index.html
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenmy $index_page_header =
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen '<HTML>\n' .
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen ' <HEAD>\n' .
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen ' <TITLE>@TITLE@</TITLE>\n' .
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen ' <META NAME="author" CONTENT="@AUTHOR@">\n' .
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen ' <META NAME="generator" CONTENT="webrev for svn">\n' .
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen# ' <META NAME="copyright" CONTENT="@COPYRIGHT@">\n' .
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen ' </HEAD>\n' .
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ' <BODY BGCOLOR="#FFFFFF">\n' .
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen ' <FONT FACE="arial,sans">\n' .
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen ' <CENTER><FONT SIZE=+1><B>@TITLE@</B></FONT></CENTER><P>\n';
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen# HTML page footer template for index.html
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainenmy $index_page_footer =
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen ' </FONT>\n' .
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen ' <HR SIZE=1 NOSHADE>\n' .
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen ' <FONT FACE="arial,sans" SIZE="-2">\n' .
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen ' Webrev report generated by @UNAME@@@HOSTNAME@ on @DATE@.\n' .
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen ' </FONT>\n' .
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen ' </BODY>\n' .
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen '</HTML>\n';
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen# HTML page header template for the diff pages
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenmy $file_page_header = $index_page_header;
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen# HTML page footer template for the diff pages
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainenmy $file_page_footer = $index_page_footer;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen# Map status to file name
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainenmy %file_status;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen# Descriptions of file status flags
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainenmy %status_desc = (' ', 'No change',
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen 'A', 'New',
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen 'C', '<FONT COLOR="#FF4444">Conflicted</FONT>',
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen 'D', 'Deleted',
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen 'G', 'Merged',
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen 'I', 'Ignored',
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen 'M', 'Modified',
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen 'R', 'Replaced',
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen '?', '<FONT COLOR="#FF4444">Not under version control</FONT>',
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen '!', 'Missing');
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen# Map property change status to file name
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen# FIXME: currently these are not used, but should be.
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainenmy %file_prop;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen# Descriptions of file status flags
2d28870ca63f2d92e315c43dced03b162afc5006Timo Sirainenmy %prop_desc = (' ', 'No change',
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen 'C', 'Conflicted',
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen 'M', 'Modified');
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainenmy $scm;
de3466de0dcc4b0da5a1205591cb1fb99eb1392fTimo Sirainen
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainenmy %file_hist;
de3466de0dcc4b0da5a1205591cb1fb99eb1392fTimo Sirainen
de3466de0dcc4b0da5a1205591cb1fb99eb1392fTimo Sirainenmy $overwrite = O_EXCL;
de3466de0dcc4b0da5a1205591cb1fb99eb1392fTimo Sirainen
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainensub msg_fatal ($) {
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen my $msg = shift;
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen print STDERR "ERROR: $msg\n";
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen exit (1);
ad3951538244a30d06b1640204e053d814d22a4eTimo Sirainen}
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainensub msg_error ($) {
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen my $msg = shift;
917f556f14686178586b4b8c8184c5b52db987f1Timo Sirainen print STDERR "ERROR: $msg\n";
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen}
917f556f14686178586b4b8c8184c5b52db987f1Timo Sirainen
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainensub msg_warning ($) {
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen my $msg = shift;
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen print STDERR "WARNING: $msg\n";
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen}
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen# fill the %file_status map based on svn status / cvs status output
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainensub get_changed_files () {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen if ($scm eq "svn") {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my @lines = `LC_ALL=C svn --non-interactive status` or msg_fatal ('"svn status" failed');
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen foreach my $line (@lines) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen chomp ($line);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($line =~ /^(.)(.)(.)(.)(.)(.) (.*)/) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $file_status{$7} = $1;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $file_prop{$7} = $2;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $file_hist{$7} = $4;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen } else {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen msg_warning ("Cannot process svn status output: $line");
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen } elsif ($scm eq "cvs") {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen # map CVS status names to svn status flags
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my %status_map = ('Locally Added', 'A',
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen 'Locally Modified', 'M',
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen 'Needs Merge', 'M',
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen 'Needs Checkout', '!',
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen 'File had conflicts on merge', 'C');
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my @lines = `LC_ALL=C cvs -z3 status 2>&1 | egrep '(^\\? |^cvs status: Examining |Status:)' | grep -v Up-to-date`
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen or msg_fatal ('"cvs status" failed');
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $dir = "";
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen foreach my $line (@lines) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen chomp ($line);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen if ($line =~ /^cvs status: Examining (.*)/) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $dir = "$1/";
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen } elsif ($line =~ /^File: no file (.+)\s+Status: (.*)/) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen if (defined ($status_map{$2})) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $file_status{"$dir$1"} = $status_map{$2};
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen }
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen } elsif ($line =~ /^File: (.*\S)\s+Status: (.*)/) {
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen if (defined ($status_map{$2})) {
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen $file_status{"$dir$1"} = $status_map{$2};
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen } elsif ($line =~ /^? (.*)/) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $f0 = $1;
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen if (-d $f0) {
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen my @files = `find $f0 -type f -print | sort`;
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen foreach my $f (@files) {
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen chomp ($f);
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen $file_status{"$f"} = '?';
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen }
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen } else {
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen $file_status{"$f0"} = '?';
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen }
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen } else {
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen msg_warning ("Cannot process cvs status output: $line");
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen }
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen }
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen }
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen}
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen# fill in values in the HTML templates
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainenmy $uname;
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainenmy $author;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenmy $hostname;
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainensub eval_template ($;$) {
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen my $str = shift;
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen my $title = shift;
3281669db44d09a087a203201248abbc81b3cc1aTimo Sirainen
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen $title = "" unless defined $title;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen if (not defined ($uname)) {
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen $uname = `logname`;
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen chomp ($uname);
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen }
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen if (not defined ($author)) {
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen $author = (getpwnam $uname)[6];
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen }
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen if (not defined ($hostname)) {
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen $hostname = `/bin/hostname`;
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen chomp ($hostname);
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen }
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen my $date = `/bin/date`;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen chomp ($date);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen $str =~ s/\@TITLE\@/$title/g;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen $str =~ s/\@AUTHOR\@/$author/g;
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen $str =~ s/\@UNAME\@/$uname/g;
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen $str =~ s/\@HOSTNAME\@/$hostname/g;
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen $str =~ s/\@DATE\@/$date/g;
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen $str =~ s/\\n/\n/g;
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen return $str;
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen}
62bf16bd8bb79e308e64110ae8d0b2a55a4c1490Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen# replace html special chars with corresponding entities
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainensub html_encode ($) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen my $str = shift;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen $str =~ s/&/&amp;/g;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen $str =~ s/</&lt;/g;
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen $str =~ s/>/&gt;/g;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen $str =~ s/\t/ /g;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return $str;
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen}
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainensub make_base_dir ($$) {
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen my $webrev_dir = shift;
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen my $file = shift;
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen system ("mkdir -p $webrev_dir/$file");
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen if ($? != 0) {
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen msg_error ("Failed to create directory $webrev_dir/$file");
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen return 0;
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen }
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen return 1;
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen}
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainensub gen_diff_new ($$) {
b07cb607ae8864e7784787a9db96880db1f50e52Timo Sirainen my $webrev_dir = shift;
b07cb607ae8864e7784787a9db96880db1f50e52Timo Sirainen my $file = shift;
b07cb607ae8864e7784787a9db96880db1f50e52Timo Sirainen my $basename = basename ($file);
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen system ("rm -f $webrev_dir/$file/new.$basename; cp $file $webrev_dir/$file/new.$basename");
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen if ($? != 0) {
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen msg_fatal ("failed to copy file $file to $webrev_dir/$file");
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen }
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen return "[<A HREF=\"$file/new.$basename\">new</A>] ";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen}
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainensub gen_diff_old ($$) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $webrev_dir = shift;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $file = shift;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $basename = basename ($file);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen system ("rm -f $webrev_dir/$file/old.$basename");
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($? != 0) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen return undef;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($scm eq 'svn') {
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen system ("svn --non-interactive cat -r BASE $file > $webrev_dir/$file/old.$basename");
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($? != 0) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen return undef;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen } elsif ($scm eq 'cvs') {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $rev=`LC_ALL=C cvs -z3 status $file | grep 'Working revision' | cut -f2 -d:`;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen chomp ($rev);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $CVSDIR = dirname ($file) . "/CVS";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $CVSROOT = `cat $CVSDIR/Root`;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen chomp ($CVSROOT);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $REPO = `cat $CVSDIR/Repository`;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen chomp ($REPO);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen system ("mkdir -p $webrev_dir/tmp");
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($? != 0) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen return undef;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen system ("cd $webrev_dir/tmp && LC_ALL=C cvs -q -z3 -d $CVSROOT co -r$rev $REPO/$basename >/dev/null 2>&1 && mv $REPO/$basename $webrev_dir/$file/old.$basename && cd / && rm -rf $webrev_dir/tmp");
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($? != 0) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen return undef;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
37f96554a5734557cd454691d163e602d36384b4Timo Sirainen }
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen return "[<A HREF=\"$file/old.$basename\">old</A>] ";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen}
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen# create the unified diff page and return the [udiff] link
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainensub gen_diff_udiff ($$) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $webrev_dir = shift;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $file = shift;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $basename = basename ($file);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my @diff;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($scm eq 'svn') {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen @diff = `svn --non-interactive diff $file`;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen } elsif ($scm eq 'cvs') {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen @diff = `cd $webrev_dir/$file; /usr/bin/diff -u old.$basename new.$basename`;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen system ("rm -f $webrev_dir/$file/udiff.html");
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($? != 0) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen return undef;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen sysopen (DIFF, "$webrev_dir/$file/udiff.html", O_WRONLY | $overwrite | O_CREAT) or
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen msg_error ("failed to create file $webrev_dir/$file/udiff.html");
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen print DIFF eval_template ($file_page_header, "Unified diff of $file");
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen print DIFF "<TT><PRE>\n";
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen foreach my $line (@diff) {
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen chomp ($line);
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen $line = html_encode ($line);
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen if ($line =~ /^---/) {
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen print DIFF "<FONT COLOR=\"green\" SIZE=\"+1\"><b>$line</b></FONT>\n";
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen } elsif ($line =~ /^@@/) {
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen print DIFF "<FONT COLOR=\"red\" SIZE=\"+1\"><b>$line</b></FONT>\n";
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen } elsif ($line =~ /^\+\+\+/) {
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen print DIFF "<FONT COLOR=\"red\" SIZE=\"+1\"><b>$line</b></FONT>\n";
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen } elsif ($line =~ /^\+/) {
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen print DIFF "<FONT COLOR=\"blue\"><b>$line</b></FONT>\n";
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen } elsif ($line =~ /^\*\*\*/) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "<FONT COLOR=\"red\" SIZE=\"+1\"><b>$line</b></FONT>\n";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen } elsif ($line =~ /^-/) {
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen print DIFF "<FONT COLOR=\"brown\">$line</FONT>\n";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen } else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "$line\n";
dce232dfbb2244555299dffb3618a4724748d260Timo Sirainen }
37f96554a5734557cd454691d163e602d36384b4Timo Sirainen }
37f96554a5734557cd454691d163e602d36384b4Timo Sirainen print DIFF "</PRE></TT>\n";
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen print DIFF eval_template ($file_page_footer);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen close DIFF;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return "[<A HREF=\"$file/udiff.html\">udiff</A>] ";
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen# create the context diff page and return the [cdiff] link
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainensub gen_diff_cdiff ($$) {
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen my $webrev_dir = shift;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen my $file = shift;
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen my $basename = basename ($file);
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen if (! -f "$webrev_dir/$file/new.$basename") {
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen gen_diff_new ($webrev_dir, $file);
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen }
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen if (! -f "$webrev_dir/$file/old.$basename") {
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen gen_diff_old ($webrev_dir, $file);
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen }
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen my @diff = `cd $webrev_dir/$file; /usr/bin/diff -c old.$basename new.$basename`;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen system ("rm -f $webrev_dir/$file/cdiff.html");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if ($? != 0) {
5314b66fca6b2cf6b749d296a30a5eb039e0e9baTimo Sirainen return undef;
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen }
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen sysopen (DIFF, "$webrev_dir/$file/cdiff.html", O_WRONLY | $overwrite | O_CREAT) or
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen msg_error ("failed to create file $webrev_dir/$file/cdiff.html");
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen print DIFF eval_template ($file_page_header, "Context diff of $file");
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen print DIFF "<TT><PRE>\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen foreach my $line (@diff) {
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen chomp ($line);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $line = html_encode ($line);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($line =~ /^\+/) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "<FONT COLOR=\"blue\"><b>$line</b></FONT>\n";
37f96554a5734557cd454691d163e602d36384b4Timo Sirainen } elsif ($line =~ /^---/) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "<FONT COLOR=\"green\" SIZE=\"+1\"><b>$line</b></FONT>\n";
37f96554a5734557cd454691d163e602d36384b4Timo Sirainen } elsif ($line =~ /^\*\*\*/) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "<FONT COLOR=\"red\" SIZE=\"+1\"><b>$line</b></FONT>\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } elsif ($line =~ /^-/) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "<FONT COLOR=\"brown\">$line</FONT>\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } elsif ($line =~ /^!/) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "<FONT COLOR=\"blue\">$line</FONT>\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "$line\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
a6de00f8d3f65335149f6fe828fca9da6328d42aTimo Sirainen print DIFF "</PRE></TT>\n";
a6de00f8d3f65335149f6fe828fca9da6328d42aTimo Sirainen print DIFF eval_template ($file_page_footer);
37f96554a5734557cd454691d163e602d36384b4Timo Sirainen close DIFF;
37f96554a5734557cd454691d163e602d36384b4Timo Sirainen return "[<A HREF=\"$file/cdiff.html\">cdiff</A>] ";
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen}
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen# add a line to the array representing either the left of the right side
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen# of an sdiff. Lines are wrapped if longer than $SDIFF_MAX_LINE
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen# returns the number of lines actually added to the array
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen#
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen# $ref is a reference to the array
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen# $start is printed before the line
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen# $line is the line itself
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen# $end is printed to the end of the line
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen# $indent_len is the number of chars to indent wrapped lines (because of the
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen# line numbers
b07cb607ae8864e7784787a9db96880db1f50e52Timo Sirainensub push_line ($$$$$) {
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen my $ref = shift;
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen my $start = shift;
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen my $line = shift;
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen my $end = shift;
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen my $indent_len = shift;
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen my $indent_str = sprintf ("%${indent_len}s ", "");
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (length ($line) <= $SDIFF_MAX_LINE) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $line = html_encode ($line);
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainen push (@$ref, "$start$line$end");
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainen return 1;
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainen }
dce232dfbb2244555299dffb3618a4724748d260Timo Sirainen my $l = 0;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $lstart = substr ($line, 0, $SDIFF_MAX_LINE);
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainen $line = substr ($line, $SDIFF_MAX_LINE);
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainen $lstart = html_encode ($lstart);
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainen my $the_line = "$start$lstart";
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainen $l++;
6140ef2418350dce8fba4706b63fe547549ed3e6Timo Sirainen while (length($line) > $SDIFF_MAX_LINE) {
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainen $lstart = substr ($line, 0, $SDIFF_MAX_LINE);
f94e1eb89b911e7bef709a25580590c3fff594acTimo Sirainen $line = substr ($line, $SDIFF_MAX_LINE);
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen $lstart = html_encode ($lstart);
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen $the_line = "$the_line\n$indent_str$lstart";
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen $l++;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $line = html_encode ($line);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $the_line = "$the_line\n$indent_str$line$end";
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen push (@$ref, $the_line);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $l++;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen return $l;
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen}
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainensub add_empty_line ($$) {
33502e55a9bf4cafcd184ca9b114c126e420f856Timo Sirainen my $ref = shift;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $len = shift;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $line = "";
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen while ($len) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $line = "$line\n";
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $len--;
88b9f9eb91da632d3e941fe4276f8ace03205b25Timo Sirainen }
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen# push (@$ref, "<PRE STYLE=\"margin: 1pt\">$line</PRE>");
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen push (@$ref, $line);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen}
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainensub extend_last_line ($$) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $ref = shift;
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $len = shift;
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $line = pop (@$ref);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen while ($len) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $line = "$line\n";
88b9f9eb91da632d3e941fe4276f8ace03205b25Timo Sirainen $len--;
88b9f9eb91da632d3e941fe4276f8ace03205b25Timo Sirainen }
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen push (@$ref, $line);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen}
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen# generate the sdiff page and return the [sdiff] link
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainensub gen_diff_sdiff ($$) {
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen my $webrev_dir = shift;
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen my $file = shift;
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen my $basename = basename ($file);
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen # we're going to work from a unified diff between the old and the new files
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen # make sure they exist
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen if (! -f "$webrev_dir/$file/new.$basename") {
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen gen_diff_new ($webrev_dir, $file);
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen }
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen if (! -f "$webrev_dir/$file/old.$basename") {
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen gen_diff_old ($webrev_dir, $file);
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen }
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen my $total_lines = `cat $webrev_dir/$file/old.$basename | wc -l`;
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen chomp ($total_lines);
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen $total_lines++;
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $line_nr_len = length ("$total_lines");
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my @diff = `cd $webrev_dir/$file; /usr/bin/diff -U $SDIFF_CONTEXT old.$basename new.$basename`;
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen # the 1st 2 lines are the file names
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $l = shift (@diff); chomp ($l);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my @left = ("<FONT COLOR=\"red\" SIZE=\"+1\"><b>$l</b></FONT>\n");
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $l = shift (@diff); chomp ($l);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my @right = ("<FONT COLOR=\"green\" SIZE=\"+1\"><b>$l</b></FONT>\n");
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen # line numbers on the left and right side
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $left_line;
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $right_line;
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $line = shift (@diff);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen chomp ($line);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen while (@diff) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen # start of a block
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen if ($line =~ /^\@\@ -([0-9]+),[0-9]+ \+([0-9]+),[0-9]+ \@\@/) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $left_line = sprintf ("%${line_nr_len}s",$1);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $right_line = sprintf ("%${line_nr_len}s",$2);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen push (@left, "<HR SIZE=1 NOSHADE>");
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen push (@right, "<HR SIZE=1 NOSHADE>");
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $line = shift (@diff);
c37098f8ce6d512ba41f09564d04ed25720f0a77Timo Sirainen chomp ($line);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen next;
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen }
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen # new lines added to the file: print them on the right side in blue
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen if ($line =~ /^\+(.*)/) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $n = push_line (\@right, "<FONT COLOR=\"blue\">$right_line ", $1, "</FONT>", $line_nr_len);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen # print an equal number of blank lines on the left side
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen add_empty_line (\@left, $n);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $right_line = sprintf ("%${line_nr_len}s", ++$right_line);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen $line = shift (@diff);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen chomp ($line);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen next;
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen # lines deleted
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my @dellines;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen while ($line =~ /^\-(.*)/) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen push (@dellines, $1);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $line = shift (@diff);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen chomp ($line);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen # if deleted lines are immediately followed by added lines,
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen # then some of the deleted lines are actually changed lines.
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen # print them in blue on both sides
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen while ($line =~ /^\+(.*)/) {
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen my $line1 = $1;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if (@dellines) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $line2 = shift (@dellines);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $n1 = push_line (\@left, "<FONT COLOR=\"blue\">$left_line ", $line2, "</FONT>", $line_nr_len);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $n1--;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $left_line = sprintf ("%${line_nr_len}s", ++$left_line);
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen my $n2 = push_line (\@right, "<FONT COLOR=\"blue\">$right_line ", $line1, "</FONT>", $line_nr_len);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $n2--;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $right_line = sprintf ("%${line_nr_len}s", ++$right_line);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($n2 > $n1) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $n2 -= $n1;
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen $n1 = 0;
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen } else {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $n1 -= $n2;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen $n2 = 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen extend_last_line (\@left, $n2) if $n2;
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen extend_last_line (\@right, $n1) if $n1;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen } else {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen # no deleted lines: print the new lines on the right side
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $n = push_line (\@right, "<FONT COLOR=\"blue\">$right_line ", $line1, "</FONT>", $line_nr_len);
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen add_empty_line (\@left, $n);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $right_line = sprintf ("%${line_nr_len}s", ++$right_line);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
9b6eb5a72ffe61579e24c6ae4c6ce3d4e9104b95Timo Sirainen $line = shift (@diff);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen chomp ($line);
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen }
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen # deleted lines remain, print them in brown on the left side
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen while (@dellines) {
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen my $line2 = shift (@dellines);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen my $n = push_line (\@left, "<FONT COLOR=\"brown\">$left_line ", $line2, "</FONT>", $line_nr_len);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $left_line = sprintf ("%${line_nr_len}s", ++$left_line);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen add_empty_line (\@right, $n);
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen }
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen # unchanged (context) lines
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen if ($line =~ /^[^+-]/) {
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen push_line (\@right, "$right_line ", $line, "", $line_nr_len);
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen push_line (\@left, "$left_line ", $line, "", $line_nr_len);
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen $left_line = sprintf ("%${line_nr_len}s", ++$left_line);
f26ef7a3a562dc42a1e9a4dde546bd30df3241e8Timo Sirainen $right_line = sprintf ("%${line_nr_len}s", ++$right_line);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else {
37e5638ddf924fd4a07623095dbc028c564f7192Timo Sirainen next;
37e5638ddf924fd4a07623095dbc028c564f7192Timo Sirainen }
d48fcf2c089269a967fb9efdacc428ace89fc91cTimo Sirainen # fetch the next line if exists
37e5638ddf924fd4a07623095dbc028c564f7192Timo Sirainen if (@diff) {
d48fcf2c089269a967fb9efdacc428ace89fc91cTimo Sirainen $line = shift (@diff);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen chomp ($line);
2e5d624013c30633e8ded148d338ce46c321a995Timo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen # write out the report
1e1549f93601770d1bddf702baf55c593e3d97e9Timo Sirainen system ("rm -f $webrev_dir/$file/sdiff.html");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if ($? != 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return undef;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen sysopen (DIFF, "$webrev_dir/$file/sdiff.html", O_WRONLY | $overwrite | O_CREAT) or
d2945436697f00504ef2b3af6afbd8a097e5eed2Timo Sirainen msg_error ("failed to create file $webrev_dir/$file/sdiff.html");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF eval_template ($file_page_header, "Side by side diff of $file");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "<TABLE COLS=2 BORDER=1 CELLSPACING=0>\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "<TR><TD VALIGN=top>\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "<TABLE WIDTH=100% COLS=1 BORDER=0 CELLSPACING=0 CELLPADDING=0>\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen my $col = 1;
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen foreach my $line (@left) {
c8296ac1ed68ed5c5168de545b76f9b27fc76d35Timo Sirainen if ($col) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print DIFF "<TR><TD BGCOLOR=#DDDDDD><PRE STYLE=\"margin: 1pt;\">$line\n</PRE></TD></TR>\n";
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen } else {
37e5638ddf924fd4a07623095dbc028c564f7192Timo Sirainen print DIFF "<TR><TD><PRE STYLE=\"margin: 1pt;\">$line\n</PRE></TD></TR>\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen $col = 1 - $col;
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen print DIFF "</TABLE></TD>\n";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen print DIFF "<TD VALIGN=top>\n";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen print DIFF "<TABLE WIDTH=100% COLS=1 BORDER=0 CELLSPACING=0 CELLPADDING=0>\n";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen $col = 1;
dce232dfbb2244555299dffb3618a4724748d260Timo Sirainen foreach my $line (@right) {
dce232dfbb2244555299dffb3618a4724748d260Timo Sirainen if ($col) {
dce232dfbb2244555299dffb3618a4724748d260Timo Sirainen print DIFF "<TR><TD BGCOLOR=#DDDDDD><PRE STYLE=\"margin: 1pt;\">$line\n</PRE></TD></TR>\n";
dce232dfbb2244555299dffb3618a4724748d260Timo Sirainen } else {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen print DIFF "<TR><TD><PRE STYLE=\"margin: 1pt;\">$line\n</PRE></TD></TR>\n";
57b523eeb99ed5d7f5002907a409cdef54353ce5Timo Sirainen }
6380f2bc729a03b328793e8ad6ba7587620fa184Timo Sirainen $col = 1 - $col;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen print DIFF "</TABLE></TD></TR>\n";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen print DIFF "</TABLE>\n";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen print DIFF eval_template ($file_page_footer);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen close DIFF;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen return "[<A HREF=\"$file/sdiff.html\">sdiff</A>] ";
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen}
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainensub gen_diff_patch ($$) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $webrev_dir = shift;
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen my $file = shift;
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen my $basename = basename ($file);
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($scm eq 'svn') {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen system ("rm -f $webrev_dir/$file/$basename.diff; svn --non-interactive diff $file > $webrev_dir/$file/$basename.diff");
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen } elsif ($scm eq 'cvs') {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen system ("rm -f $webrev_dir/$file/$basename.diff; cvs -q diff -up $file > $webrev_dir/$file/$basename.diff");
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen }
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen if ($? != 0) {
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen return undef;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen }
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen return "[<A HREF=\"$file/$basename.diff\">patch</A>] ";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen# map ChangeLog entries to files
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainenmy %changelog_entry;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen# find updated ChangeLog files and extract the entries for each file
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainensub read_changelog_entries () {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen foreach my $file (sort keys %file_status) {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen if ($file eq "ChangeLog" or $file =~ /\/ChangeLog$/) {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my @chlog_lines;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen if ($scm eq 'svn') {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen @chlog_lines = `svn --non-interactive diff $file | grep "^\+"`;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen } elsif ($scm eq 'cvs') {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen @chlog_lines = `cvs -q diff -u $file | grep "^\+"`;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen }
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $dirname = dirname ($file);
3281669db44d09a087a203201248abbc81b3cc1aTimo Sirainen if ($dirname eq ".") {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $dirname = "";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else {
be044d4f3d08652d7332cdec5aaf8391474908bbTimo Sirainen $dirname = "$dirname/";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen }
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen while (@chlog_lines) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen my $line = shift (@chlog_lines);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen chomp ($line);
be044d4f3d08652d7332cdec5aaf8391474908bbTimo Sirainen # * file: foo bar
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen if ($line =~ /^\+(\s+\* \S+.*)/) {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $entry = $1;
be044d4f3d08652d7332cdec5aaf8391474908bbTimo Sirainen my $ecat = $1;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $line = shift (@chlog_lines);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen chomp ($line);
be044d4f3d08652d7332cdec5aaf8391474908bbTimo Sirainen # read all lines until the next
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen # * file: foo bar
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen # entry
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen while (defined ($line) and $line =~ /^\+(\s+[^*].*)/) {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $entry = "$entry\n$1";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $ecat = "$ecat$1";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $line = shift (@chlog_lines);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen chomp ($line);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen }
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $ecat =~ s/^\s*\*\s*//;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen # assign the same entry to each file listed with
031d075daf75b74b286711c1b6f64c3ae70e541bTimo Sirainen # commas before the first :
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen while ($ecat =~ /^([^:,]+)[:,]\s*(.*)/) {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $changelog_entry{"$dirname$1"} = "$entry\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen $ecat = $2;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unshift (@chlog_lines, $line);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen }
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen }
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen}
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen################ MAIN ###################################################
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainensub main ($) {
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen my $webrev_dir = shift;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen
30003461d9c5b090384b252260916cf50954d943Timo Sirainen system ("mkdir -p $webrev_dir");
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen if ($? != 0) {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen msg_fatal ("Webrev directory could not be created");
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen }
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen
30003461d9c5b090384b252260916cf50954d943Timo Sirainen sysopen (INDEX, "$webrev_dir/index.html", O_WRONLY | $overwrite | O_CREAT) or
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen msg_fatal ("failed to create file $webrev_dir/index.html");
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen print "Finding changed files...\n";
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen get_changed_files ();
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen print "Reading ChangeLogs...\n";
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen read_changelog_entries ();
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen my $title = `pwd`;
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen chomp ($title);
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen $title = basename ($title . " Webrev");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX eval_template ($index_page_header, $title);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $total_new = 0;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $total_deleted = 0;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $total_changed = 0;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $total_unchanged = 0;
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen my $total_non_svn = 0;
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen print "Processing files...\n";
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen foreach my $file (sort keys %file_status) {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print " $file\n";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "<P><B>$file</B> ($status_desc{$file_status{$file}})<BR>\n";
4145cbac82bfc0c8bfeceeca0ef841700117930cTimo Sirainen print INDEX "&nbsp; &nbsp; &nbsp; &nbsp;";
4145cbac82bfc0c8bfeceeca0ef841700117930cTimo Sirainen make_base_dir ($webrev_dir, $file) or
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "<P>\n", next;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen if ($file_status{$file} eq 'A') {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX gen_diff_new ($webrev_dir, $file);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $lines = `cat $file | wc -l`;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen chomp ($lines);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "<BR>&nbsp; &nbsp; &nbsp; &nbsp;";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "$lines new line(s)\n";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $total_new += $lines;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen } elsif ($file_status{$file} eq 'D') {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX gen_diff_old ($webrev_dir, $file);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "<BR>&nbsp; &nbsp; &nbsp; &nbsp;";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen my $basename = basename ($file);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $lines = `cat $webrev_dir/$file/old.$basename | wc -l`;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen chomp ($lines);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "$lines deleted line(s)\n";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $total_deleted += $lines;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen } elsif ($file_status{$file} eq '?') {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen next if -d $file;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX gen_diff_new ($webrev_dir, $file);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "<BR>&nbsp; &nbsp; &nbsp; &nbsp;";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $lines = `cat $file | wc -l`;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen chomp ($lines);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "$lines new line(s) not under svn control\n";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $total_non_svn += $lines;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen } elsif ($file_status{$file} eq 'M') {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $label = gen_diff_old ($webrev_dir, $file);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen next if not defined $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $label = gen_diff_new ($webrev_dir, $file);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen next if not defined $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $label = gen_diff_udiff ($webrev_dir, $file);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen next if not defined $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $label = gen_diff_cdiff ($webrev_dir, $file);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen next if not defined $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $label = gen_diff_sdiff ($webrev_dir, $file);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen next if not defined $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX $label;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $label = gen_diff_patch ($webrev_dir, $file);
39ed514f9d401b3cb589595c6a2f532050254d77Timo Sirainen my $basename = basename ($file);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $changed_lines = `diff -c $webrev_dir/$file/old.$basename $webrev_dir/$file/new.$basename | grep '^! ' | wc -l`;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen chomp ($changed_lines);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $deleted_lines = `diff -c $webrev_dir/$file/old.$basename $webrev_dir/$file/new.$basename | grep '^- ' | wc -l`;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen chomp ($deleted_lines);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $new_lines = `diff -c $webrev_dir/$file/old.$basename $webrev_dir/$file/new.$basename | grep '^+ ' | wc -l`;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen chomp ($new_lines);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $total_lines = `cat $webrev_dir/$file/old.$basename | wc -l`;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen chomp ($total_lines);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen my $unchanged_lines = $total_lines - $deleted_lines - $changed_lines;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "<BR>&nbsp; &nbsp; &nbsp; &nbsp;";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "$new_lines line(s) new / $deleted_lines line(s) deleted / $changed_lines line(s) updated / $unchanged_lines line(s) unchanged\n";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $total_new += $new_lines;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $total_deleted += $deleted_lines;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $total_changed += $changed_lines;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen $total_unchanged += $unchanged_lines;
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen }
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen if (defined ($changelog_entry{$file})) {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "<PRE>\n";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX $changelog_entry{$file};
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print INDEX "</PRE>\n";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen } elsif ($file ne "ChangeLog" and not $file =~ /\/ChangeLog$/) {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "<BR>&nbsp; &nbsp; &nbsp; &nbsp;";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen print INDEX "<FONT COLOR=red>No ChangeLog entry found</FONT><BR>\n";
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen }
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen }
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "<P><B>Total</B>: $total_new line(s) new / $total_deleted line(s) deleted / $total_changed line(s) updated / $total_unchanged line(s) unchanged<BR>\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if ($total_non_svn) {
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen print INDEX "An additional $total_non_svn line(s) not under source control<P>\n";
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen print INDEX eval_template ($index_page_footer);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen close INDEX;
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen print "Done.\n"
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen}
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainenif ((@ARGV != 1) or ($ARGV[0] eq "-h") or ($ARGV[0] eq "--help")) {
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen print "Usage: webrev /path/to/webrev/dir\n\n";
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen print "Run this script inside a Subversion or CVS controlled directory\n";
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen print "to create an html code review document.\n";
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen print "The argument is a directory where the output is written.\n";
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen print "The svn or cvs command must be in your PATH and should not\n";
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen print "require interaction (e.g. use ssh-add first)\n";
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen exit(1);
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen}
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainenif (-d '.svn') {
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen $scm = 'svn';
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen} elsif (-d 'CVS') {
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen $scm = 'cvs';
4145cbac82bfc0c8bfeceeca0ef841700117930cTimo Sirainen} else {
854255e62c956846537335b8c38f921a7e4b3afbTimo Sirainen msg_fatal ("No CVS or Subversion control files found in this directory");
854255e62c956846537335b8c38f921a7e4b3afbTimo Sirainen}
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenif (-d "$ARGV[0]/.svn" or -d "$ARGV[0]/CVS") {
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen msg_fatal ("The target directory should not be svn or CVS controlled");
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen}
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainenif (-f "$ARGV[0]/index.html") {
5b6470e0e2ef4012430cdeca7d9b89c1278a0ed4Timo Sirainen print "Overwrite files in $ARGV[0] (y/n)? ";
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen my $ans = lc(<STDIN>);
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen chomp ($ans);
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen if ($ans eq 'y' or $ans eq 'yes') {
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen $overwrite = O_CREAT;
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen }
3b55c4f0e2ab51e2607556dde8d36360296b29e4Timo Sirainen}
03f4c5f3502801f5b318f464cc75313a88558805Timo Sirainen
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainenmain ($ARGV[0]);
009d6d90b33bc7f64fa8251ac392cc87a835b833Timo Sirainen