#!/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: # => # 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() { /... \#(\d+) change (\d+)/ and do { $revToChange{$1} = $2 ; } } ; close P4 ; &P4CGI::p4call(*P4,"annotate -a \"$file$trev\"") ; my $info = 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 $file\#$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() { /^$key/ and do { while() { last if /^:/ ; print ; } last ; } } print &P4CGI::end_framedTable(), "
" ; } # 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 "\n" ; unless($isExplorer) { print "" ; print "" if $showdeleted ; print "\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() { chomp ; s/^(\d+)-(\d+): // and do { my ($firstrev,$lastrev,$line) = ($1,$2,$_) ; my $addspaces = $revDigits - digits($firstrev) ; $firstrev = "$firstrev" ; while($addspaces-- > 0) { $firstrev .= " " ; } ; if($lastrev < $rev) { my $r = $lastrev + 1 ; $addspaces = $revDigits - digits($r) ; $lastrev = "$r" ; 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="".sprintf("%${lineNoDigits}d:",$lineNo)."" ; } else { $lineNoStr="$emptyLineNo " ; } } my $revclass ; if($lastRevStr eq $revStr) { $revStr = "$emptyRevStr" ; $firstrev = "" ; $lastrev = "" ; $revclass="fileViewerRevEmpty" ; } else { $lastRevStr = $revStr ; $revclass="fileViewerRev" ; } ; if($isExplorer) { if($cclass ne "") { push @dataC , "". "$revStr ". "$lineNoStr". "" . "$line ". "" ; } else { push @dataC , "". "$revStr ". "$lineNoStr". "$line " ; } } else { print "" ; print "" if $showdeleted ; print "\n" ; } } } if($isExplorer) { print "\n", " \n", "\n" ; } ; print "
Add
Rev.
Del
Rev.
LineContent
$firstrev$lastrev$lineNoStr$line
", join("\n",@dataC), "
" ; 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.
The contents may be colorized for some file types (html, perl and c source).
The contents is displayed in a table with three columns:
  1. The first column contain the revision where the line was added.
  2. The second column shows source line numbers.
  3. The third column shows the file content.
:MSIE, Show deleted This page show all lines that ever has been in the file for a specific revision of it.
The contents may be colorized for some file types (html, perl and c source).
The contents is displayed in a table with three columns:
  1. The first column contain the revision where the line was added prepended with A: and, optionally the revision where the line was deleted prepended with a D:.
  2. The second column shows source line numbers.
  3. The third column shows the file content.
:Other, Hide deleted This page show contents of a specific revision of a file as text.
The contents may be colorized for some file types (html, perl and c source).
The contents is displayed in a table with three columns:
  1. The "Add Rev." column contain the revision where the line was added.
  2. The "Line" column shows source line numbers..
  3. The "Content" column shows the file content.
:Other, Show deleted This page show all lines that ever has been in the file for a specific revision of it.
The contents may be colorized for some file types (html, perl and c source).
The contents is displayed in a table with four columns:
  1. The "Add Rev." column contain the revision where the line was added.
  2. The "Del Rev." column contain the revision where the line was deleted
  3. The "Line" column shows source line numbers..
  4. The "Content" column shows the file content.