Rev 1295 | Blame | Compare with Previous | Last modification | View Log | RSS feed
################################################################################ Codestriker: Copyright (c) 2001, 2002, 2003 David Sitsky.# All rights reserved.# sits@users.sourceforge.net## This program is free software; you can redistribute it and modify it under# the terms of the GPL.# Parser object for reading the output for a perforce diff command, such# as:## p4 diff -du#package Codestriker::FileParser::PerforceDiff;use strict;use Codestriker::FileParser::UnidiffUtils;sub _make_chunk ($);sub _retrieve_file ($$);# Return the array of filenames, revision number, linenumber, whether its# binary or not, and the diff text.# Return () if the file can't be parsed, meaning it is in another format.sub parse ($$$) {my ($type, $fh, $repository) = @_;# Skip initial whitespace.my $line = <$fh>;while (defined($line) && $line =~ /^\s*$/) {$line = <$fh>;}# Array of results found.my @result = ();# Assume the repository matches this diff, unless we find evidence to# the contrary.my $repmatch = 1;# Now read the actual diff chunks.while (defined($line)) {if ($line =~ /^==== (.*)\#(\d+) \- .* ==== \((.*)\)$/) {my $filename = $1;my $revision = $2;my $file_type = $3;if ($file_type eq "ubinary" || $file_type eq "xbinary" ||$file_type eq "binary") {# Binary file, skip the next line and add the record in.$line = <$fh>;my $chunk = {};$chunk->{filename} = $filename;$chunk->{revision} = $revision;$chunk->{old_linenumber} = -1;$chunk->{new_linenumber} = -1;$chunk->{binary} = 1;$chunk->{text} = "";$chunk->{description} = "";$chunk->{repmatch} = $repmatch;push @result, $chunk;}elsif ($file_type eq "text") {# Note there may be an optional '---' and '+++' lines# before the chunk.my $lastpos = tell $fh;if (<$fh> !~ /^\-\-\-/ || <$fh> !~ /^\+\+\+/) {# Move the file pointer back.seek $fh, $lastpos, 0;}my @file_diffs = Codestriker::FileParser::UnidiffUtils->read_unidiff_text($fh, $filename, $revision, $repmatch);push @result, @file_diffs;}else {# Got knows what this is, can't parse it.return ();}} elsif ($line =~ /^==== (.*)\#(\d+) \-/) {my $filename = $1;my $revision = $2;# Now read the entire diff chunk (it may be empty if the# user hasn't actually modified the file). Note there# may be an optional '---' and '+++' lines before the# chunk.my $lastpos = tell $fh;if (<$fh> !~ /^\-\-\-/ || <$fh> !~ /^\+\+\+/) {# Move the file pointer back.seek $fh, $lastpos, 0;}my @file_diffs = Codestriker::FileParser::UnidiffUtils->read_unidiff_text($fh, $filename, $revision, $repmatch);push @result, @file_diffs;} else {# Can't parse this file.return ();}# Now read the next chunk.$line = <$fh> if defined $line;}# Return the found diff chunks.return @result;}1;