#!/usr/bin/perl -w
# -*- perl -*-
use P4CGI ;
use strict ;
#
#################################################################
# CONFIGURATION INFORMATION
# All config info should be in P4CGI.pm
#
#################################################################
#
# P4 file viewer
# View a file
#
#################################################################
use viewConfig ;
use colorView ;
$| = 1 ;
# A hash containing file extensions that can be viewed with special viewers
# Data is:
# <extension> => <semicolon separated list of:
# url - Url to be used
# typecode - Will be sent as parameter TYPE to url
# text - A text for the href to url>
# Other than the TYPE parameter mentioned above the file name (depot format) will
# be sent as FILE parameter and file revision as REV parameter.
#
# return number of digits in an integer
sub digits($) {
my $n = shift;
return int(log($n)/log(10))+1 ;
}
# Get file spec argument
my $file = &P4CGI::cgi()->param("FSPC") ;
&P4CGI::bail("No file specified") unless defined $file ;
my $showdeleted = &P4CGI::cgi()->param("SHOWDEL") ;
my $showhelp = &P4CGI::cgi()->param("HELP") ;
$showhelp="N" unless defined $showhelp ;
print STDERR "File:$file\n" ; ## DEBUG
my $ext = $file ;
$ext =~ s/^.*\.// ;
my $revision = P4CGI::cgi()->param("REV") ;
# &P4CGI::bail("No revision specified") unless defined $revision ;
$revision="" unless defined $revision ;
my $force = P4CGI::cgi()->param("FORCE") ;
print STDERR "Rev:$revision\n" ; ## DEBUG
my @legend ;
my $trev = "" ;
$trev = "\#$revision" if defined $revision ;
my @filetext ;
&P4CGI::p4call(\@filetext,"print -q \"$file$trev\"") ;
map { my $x = &P4CGI::htmlEncode($_) ; $_ = $x ; } @filetext ;
if(&P4CGI::VIEW_WITH_COLORS()) {
my $tmp = join("\n",@filetext) ;
&colorView::color($file,\$tmp) ;
@filetext = split("\n",$tmp) unless $@ ;
} ;
local *P4 ;
my %revToChange ;
&P4CGI::p4call(*P4,"filelog \"$file$trev\"") ;
while(<P4>) {
/... \#(\d+) change (\d+)/ and do {
$revToChange{$1} = $2 ;
}
} ;
close P4 ;
&P4CGI::p4call(*P4,"annotate -a \"$file$trev\"") ;
my $info = <P4> or &P4CGI::bail("Failed to read file $file$trev") ;
$info =~ /\#(\d+) - / or &P4CGI::bail("Failed to parse first line from \"p4 annotate -a $file$trev\" command") ;
my $rev = $1 ;
{
my $buttontext ;
my $helptext ;
if(defined $showdeleted) {
&P4CGI::cgi()->delete("SHOWDEL") ;
$buttontext = "Hide deleted lines" ;
$helptext = "Hide the deleted lines and revisions" ;
}
else {
&P4CGI::cgi()->param("SHOWDEL","Y") ;
$buttontext = "Show deleted lines" ;
$helptext = "Show all deleted lines and the revisions where they existed" ;
} ;
push @legend, &P4CGI::buttonCell(&P4CGI::cgi()->url(-relative => 1,
-query => 1),
$helptext,,
$buttontext) ;
if(defined $showdeleted) {
&P4CGI::cgi()->param("SHOWDEL","Y") ;
}
else {
&P4CGI::cgi()->delete("SHOWDEL") ;
} ;
};
$ext = uc($ext) ;
if(exists $viewConfig::ExtensionToType{$ext}) {
my $type = $viewConfig::ExtensionToType{$ext} ;
my ($url,$desc,$content,$about) = @{$viewConfig::TypeData{$type}} ;
push @legend, &P4CGI::buttonCell($url,
"View file $file",
"TYPE=$type",
"FSPC=$file",
"REV=$rev",
"View $desc") ;
} ;
push @legend, &P4CGI::buttonCell("fileLogView.cgi",
"View file log for $file",
"FSPC=$file",
"File log");
push @legend, &P4CGI::buttonCell("fileDownLoad.cgi",
"Download file $file",
"FSPC=$file",
"REV=$rev",
"Download") ;
{
&P4CGI::cgi()->delete("HELP") ;
my $buttontext ;
my $helptext ;
if($showhelp ne "Y") {
&P4CGI::cgi()->param("HELP","Y") ;
$buttontext = "Show help" ;
$helptext = "Show a help text that describes this page" ;
}
else {
&P4CGI::cgi()->param("HELP","N") ;
$buttontext = "Hide help" ;
$helptext = "Hide help" ;
} ;
push @legend, &P4CGI::buttonCell(&P4CGI::cgi()->url(-relative => 1,
-query => 1),
$helptext,,
$buttontext) ;
&P4CGI::cgi()->delete("HELP") ;
};
print
&P4CGI::start_page("File <tt>$file</tt>\#$rev",@legend) ;
if($showhelp eq "Y") {
print
&P4CGI::start_framedTable("Page help") ;
my $key = ":Other" ;
$key = ":MSIE" if &P4CGI::IS_MSEXPLORER() ;
$key .= ", Hide" unless defined $showdeleted ;
$key .= ", Show" if defined $showdeleted ;
while(<DATA>) {
/^$key/ and do {
while(<DATA>) {
last if /^:/ ;
print ;
}
last ;
}
}
print
&P4CGI::end_framedTable(), "<br>" ;
}
# NOTE!
# CSS support for MS-Explorer 5 and 6 is broken in the sense that it does not handle
# "white-space: pre" properly in normal mode.
# Most (all?) other recent browsers work but it is very hard do ignore Explorer, no matter
# how broken it is.......
# Sigh! The code below (and the CSS file!) differs between Explorer and other
# browsers (Netscape etc,). It would be possible to use the "Explorer method" for
# all browsers but I do not want to punish all users just because Explorer is
# a bit broken.
my $isExplorer = &P4CGI::IS_MSEXPLORER() ;
# Get number of digits required for revision and lineNo
my $lines = scalar @filetext ;
my $lineNoDigits = digits($lines) ;
my $revDigits = digits($rev) ;
$revDigits = 1 unless $revDigits > 1 ;
print
&P4CGI::start_framedTable("File ($lines lines)") ;
print "<table class=\"fileViewer\">\n" ;
unless($isExplorer) {
print "<tr><th class=\"fileViewerHeader\">Add<br>Rev.</th>" ;
print "<th class=\"fileViewerHeader\">Del<br>Rev.</th>" if $showdeleted ;
print "<th class=\"fileViewerHeader\">Line</th><th class=\"fileViewerHeader\">Content</th></tr>\n" ;
} ;
my $lastRevStr = "" ;
my $lineNo = 0 ;
my @dataC ;
my $emptyRev = substr(" ",0,$revDigits) ; # lets hope there are never more than 999,999,999,999
my $emptyLineNo = substr(" ",0,$lineNoDigits) ; # lines in a file or revisions on a file!
my $emptyRevStr ;
if(defined $showdeleted) { $emptyRevStr = "$emptyRev $emptyRev" ; }
else { $emptyRevStr = "$emptyRev" ; }
while(<P4>) {
chomp ;
s/^(\d+)-(\d+): // and do {
my ($firstrev,$lastrev,$line) = ($1,$2,$_) ;
my $addspaces = $revDigits - digits($firstrev) ;
$firstrev =
"<a class=\"normal\" title=\"Line(s) added by change $revToChange{$firstrev}. Click to view change.\" ".
" href=\"changeView.cgi?CH=$revToChange{$firstrev}\">$firstrev</a>" ;
while($addspaces-- > 0) { $firstrev .= " " ; } ;
if($lastrev < $rev) {
my $r = $lastrev + 1 ;
$addspaces = $revDigits - digits($r) ;
$lastrev =
"<a class=\"normal\" title=\"Line(s) deleted by change $revToChange{$r}. Click to view change.\" ".
" href=\"changeView.cgi?CH=$revToChange{$r}\">$r</a>" ;
while($addspaces-- > 0) { $lastrev .= " " ; } ;
}
else {
$lastrev = "" ;
}
my $cclass = "" ;
my $revStr = "XX" ;
my $lineNoStr = "$emptyLineNo " ;
if($lastrev ne "") {
next unless defined $showdeleted ;
$revStr = "A:$firstrev D:$lastrev" ;
$cclass= "class=\"deleted\"" ;
$line = &P4CGI::htmlEncode($line)
}
else {
$line = shift @filetext ;
if(defined $showdeleted) { $revStr = "A:$firstrev $emptyRev" ; }
else { $revStr = "$firstrev" ; }
$lineNo++ ;
if($lineNo == 1 or $lineNo % 5 == 0) {
$lineNoStr="<a name=\"L$lineNo\">".sprintf("%${lineNoDigits}d:",$lineNo)."</a>" ;
}
else {
$lineNoStr="<a name=\"L$lineNo\">$emptyLineNo </a>" ;
}
}
my $revclass ;
if($lastRevStr eq $revStr) {
$revStr = "$emptyRevStr" ;
$firstrev = "" ;
$lastrev = "" ;
$revclass="fileViewerRevEmpty" ;
}
else {
$lastRevStr = $revStr ;
$revclass="fileViewerRev" ;
} ;
if($isExplorer) {
if($cclass ne "") {
push @dataC , "".
"<span class=\"$revclass\">$revStr</span> ".
"<span class=\"fileViewerLineNo\">$lineNoStr</span>".
"<span $cclass>" .
"<span class=\"fileViewerData\">$line </span>".
"</span>" ;
} else {
push @dataC , "".
"<span class=\"$revclass\">$revStr</span> ".
"<span class=\"fileViewerLineNo\">$lineNoStr</span>".
"<span class=\"fileViewerData\">$line </span>" ;
}
}
else {
print "<tr><th class=\"$revclass\">$firstrev</th>" ;
print "<th class=\"$revclass\">$lastrev</th>" if $showdeleted ;
print "<th class=\"fileViewerLineNo\">$lineNoStr</th><td $cclass>$line </td></tr>\n" ;
}
}
}
if($isExplorer) {
print
"<tr>\n",
" <td class=\"fileViewerDataMSIE\"><pre>", join("\n",@dataC), "</pre></td>\n",
"</tr>\n" ;
} ;
print "</table>" ;
close P4 ;
print
&P4CGI::end_framedTable(),
&P4CGI::end_page() ;
#
# That's all folks
#
__END__
:MSIE, Hide deleted
This page show contents of a specific revision of a file as text.<br>
The contents may be colorized for some file types (html, perl and c source).<br>
The contents is displayed in a table with three columns:
<ol>
<li> The first column contain the revision where the line was added.
<li> The second column shows source line numbers.
<li> The third column shows the file content.
</ol>
:MSIE, Show deleted
This page show all lines that ever has been in the file for a specific revision of it.<br>
The contents may be colorized for some file types (html, perl and c source).<br>
The contents is displayed in a table with three columns:
<ol>
<li> The first column contain the revision where the line was added prepended with <b>A:</b> and,
optionally the revision where the line was deleted prepended with a <b>D:</b>.
<li> The second column shows source line numbers.
<li> The third column shows the file content.
</ol>
:Other, Hide deleted
This page show contents of a specific revision of a file as text.<br>
The contents may be colorized for some file types (html, perl and c source).<br>
The contents is displayed in a table with three columns:
<ol>
<li> The "Add Rev." column contain the revision where the line was added.
<li> The "Line" column shows source line numbers..
<li> The "Content" column shows the file content.
</ol>
:Other, Show deleted
This page show all lines that ever has been in the file for a specific revision of it.<br>
The contents may be colorized for some file types (html, perl and c source).<br>
The contents is displayed in a table with four columns:
<ol>
<li> The "Add Rev." column contain the revision where the line was added.
<li> The "Del Rev." column contain the revision where the line was deleted
<li> The "Line" column shows source line numbers..
<li> The "Content" column shows the file content.
</ol>
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #11 | 4916 | Fredric Fredricson | P4DB: Improved file viewer (and simplified the code) | ||
| #10 | 4306 | Fredric Fredricson |
P4DB: Hardened P4DB against malicious parameters (cross site scripting), performed some cleanup and increased version to 3.1.1. |
||
| #9 | 4237 | Fredric Fredricson | P4DB: Maybe the final submit for P4DB 3.1.0 | ||
| #8 | 4216 | Fredric Fredricson | P4DB: Another partial submit on my way to P4DB 3.1... | ||
| #7 | 4176 | Fredric Fredricson | P4DB: Still working my way to P4DB 3.1... | ||
| #6 | 4152 | Fredric Fredricson | P4DB: Some more work on tha way to version 3.1.... | ||
| #5 | 4069 | Fredric Fredricson | P4DB: More changes on the way to 3.1 | ||
| #4 | 4048 | Fredric Fredricson |
P4DB: Updated for Explorer. * Updated Style Sheet to work for Explorer as well as Netscape * Improved alternate header * Some other small fixes.... |
||
| #3 | 2875 | Fredric Fredricson | P4DB 3.0 first beta... | ||
| #2 | 1920 | Fredric Fredricson |
P4DB: Mainly some user interface fixes: * Added a small arrow that points to selection in list of options * Added tooltip help * Added user prefereces to turn the above off (or on) * Some other user interface fixes And fixed a bug in jobList.cgi and some minor bugs in label and branch viewers. |
||
| #1 | 1638 | Fredric Fredricson | P4DB: Added all (I think) files for P4DB |