#!/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 ; $file = &P4CGI::htmlEncode($file) ; my $showdeleted = &P4CGI::cgi()->param("SHOWDEL") ; my $showhelp = &P4CGI::cgi()->param("HELP") ; $showhelp="N" unless defined $showhelp ; my $revision = P4CGI::cgi()->param("REV") ; my $force = P4CGI::cgi()->param("FORCE") ; my $fileExtension = $file ; $fileExtension =~ s/^.*\.// ; $fileExtension = uc($fileExtension) ; $revision = "\#$revision" if defined $revision ; $revision = "" unless defined $revision ; my @legend ; my $filetype = "UNKNOWN" ; my $filesize = "UNKNOWN" ; local *P4 ; &P4CGI::p4call(*P4,"fstat -l -s \"$file$revision\"") ; while() { /... headType (\S+)/ and do { $filetype = $1 ; next ; } ; /... fileSize (\d+)/ and do { $filesize = $1 ; next ; } } my %revToChange ; &P4CGI::p4call(*P4,"filelog \"$file$revision\"") ; while() { /... \#(\d+) change (\d+)/ and do { $revToChange{$1} = $2 ; } } ; close P4 ; my @fileContents ; &P4CGI::p4call(\@fileContents,"print \"$file$revision\"") ; my $info = shift @fileContents; &P4CGI::bail("Failed to read file $file$revision") unless defined $info ; $info =~ /\#(\d+) - / or &P4CGI::bail("Failed to parse first line from \"p4 print/annotate -a $file$revision\" command") ; my $rev = $1 ; { my $buttontext ; my $helptext ; if($rev > 1) { 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 revision where they where deleted" ; } ; } ; push @legend, &P4CGI::buttonCell(&P4CGI::cgi()->url(-relative => 1, -query => 1), "$helptext", "$buttontext"); }; if(exists $viewConfig::ExtensionToType{$fileExtension}) { my $type = $viewConfig::ExtensionToType{$fileExtension} ; my ($url,$desc,$content,$about) = @{$viewConfig::TypeData{$type}} ; push @legend, &P4CGI::buttonCell($url, "View file $file", "TYPE=$type", "FSPC=$file", "TARGET=_blank", "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 ; $key = ":Hide" unless defined $showdeleted ; $key = ":Show" if defined $showdeleted ; while() { /^$key/ and do { while() { last if /^:/ ; print ; } last ; } } print &P4CGI::end_framedTable(), "
" ; } print &P4CGI::start_framedTable("File info"), &P4CGI::start_table(), &P4CGI::table_row({-class => "Prompt", -text => "File type:"}, $filetype), &P4CGI::table_row({-class => "Prompt", -text => "File size:"}, "$filesize Bytes"), &P4CGI::end_table(), &P4CGI::end_framedTable() ; unless($force or $filetype =~ /text/ or $filetype =~ /unicode/) { print "File type is \"$filetype\" and not text
" ; &P4CGI::cgi()->param("FORCE"=>"Y") ; print &P4CGI::buttonLink(&P4CGI::cgi()->url(-query=>1), "View file even if not text type", "View anyway"), &P4CGI::end_page() ; exit 0 ; } map { my $x = &P4CGI::htmlEncode($_) ; $_ = $x ; } @fileContents ; if(&P4CGI::VIEW_WITH_COLORS()) { my $tmp = join("\n",@fileContents) ; &colorView::color($file,\$tmp) ; @fileContents = split("\n",$tmp) unless $@ ; } ; my $lines = scalar @fileContents ; print &P4CGI::start_framedTable("File ($lines lines)") ; print "\n" ; print "" ; print "" ; print "" if $showdeleted ; print " "; print " "; print "\n" ; my $lastRevStr = "" ; my $lineNo = 0 ; my @dataC ; my $p4_depot=&P4CGI::CURR_DEPOT_NO() ; &P4CGI::p4call(*P4,"annotate -a \"$file$revision\"") ; my $firstline = ; while() { chomp ; s/^(\d+)-(\d+): // and do { my ($firstrev,$lastrev,$line) = ($1,$2,&P4CGI::rmTabs($_)) ; next if ($lastrev < $rev) and ! $showdeleted ; $firstrev = "$firstrev/$revToChange{$firstrev}" ; if($lastrev < $rev) { my $r = $lastrev + 1 ; if($showdeleted) { $lastrev = "$r/$revToChange{$r}" ; } else { $lastrev = "" ; } ; } else { $lastrev = "" ; } my $cclass = "" ; my $revStr = "XX" ; my $lineNoStr = "" ; if($lastrev ne "") { $revStr = "A:$firstrev D:$lastrev" ; $cclass= "class=\"deleted\"" ; $line = &P4CGI::htmlEncode($line) ; } else { $line = shift @fileContents ; $revStr = "A:$firstrev " ; $lineNo++ ; if($lineNo == 1 or $lineNo % 5 == 0) { $lineNoStr="$lineNo" ; } else { $lineNoStr=" " ; } } my $revclass ; if($lastRevStr eq $revStr) { $revStr = "" ; $firstrev = "" ; $lastrev = "" ; $revclass="fileViewerRevEmpty" ; } else { $lastRevStr = $revStr ; $revclass="fileViewerRev" ; } ; $line = "" unless defined $line ; while($line =~ s/(<[^>]*) ([^>]*>)/$1===SPACE===HERE===$2/g) {} ; $line =~ s/ / /g ; $line =~ s/===SPACE===HERE===/ /g ; print "" ; print "" if $showdeleted ; print "\n" ; } } ; print "
Added in rev./ch.Deleted to rev./ch.LineFile
content
$firstrev$lastrev$lineNoStr$line
" ; close P4 ; print &P4CGI::end_framedTable(), &P4CGI::end_page() ; # # That's all folks # __END__ :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 show revision and change where line was added or modified.
  2. The second column shows source line numbers..
  3. The third column shows the file content.
: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 "Added in rev." column contain the revision and change where the line was added.
  2. The "Deleted in rev." column contain the revision and change where the line was deleted. This column is empty if the line is not deleted.
  3. The third column shows source line numbers (in the current revision)
  4. The fourth column shows the file content. Deleted will be marked as:
    This is a deleted line