Rev 1293 | Go to most recent revision | 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 patch unidiffs.package Codestriker::FileParser::PatchUnidiff;use strict;use Codestriker::FileParser::UnidiffUtils;# Return the array of filenames, revision number, linenumber and the diff text.# Return () if the file can't be parsed, meaning it is in another format.sub parse ($$) {my ($type, $fh) = @_;# Array of results found.my @result = ();# Ignore any whitespace at the start of the file.my $line = <$fh>;while (defined($line)) {# Values associated with the diff.my $revision = $Codestriker::PATCH_REVISION;my $filename = "";my $old_linenumber = -1;my $new_linenumber = -1;my $binary = 0;# Skip any heading or trailing whitespace contained in the review# text.while (defined($line) && $line =~ /^\s*$/) {$line = <$fh>;}return @result unless defined $line;# For unidiffs, the diff line may appear first, but is optional,# depending on how the diff was generated. In any case, the line# is ignored.if (defined $line && $line =~ /^diff/o) {$line = <$fh>;}return () unless defined $line;# Need to check for binary file differences.# Unfortunately, when you provide the "-N" argument to diff,# it doesn't indicate new files or removed files properly. Without# the -N argument, it then indicates "Only in ...".if ($line =~ /^Binary files .* and (.*) differ$/ ||$line =~ /^Files .* and (.*) differ$/) {$filename = $1;$binary = 1;} elsif ($line =~ /^Only in (.*): (.*)$/) {$filename = "$1/$2";$binary = 1;} elsif ($line =~ /^\-\-\- \/dev\/null/o) {# File has been added.$revision = $Codestriker::ADDED_REVISION;} elsif ($line =~ /^\-\-\- (.*)\t/o) {$filename = $1;} else {return ();}if ($binary == 0) {# Now expect the +++ line.$line = <$fh>;return () unless defined $line;# Check if it is a removed file.if ($line =~ /^\+\+\+ \/dev\/null/o) {# File has been removed.$revision = $Codestriker::REMOVED_REVISION;} elsif ($line =~ /^\+\+\+ (.*)\t/o) {$filename = $1;} else {return ();}# Extract the diff chunks for this file.my @file_diffs = Codestriker::FileParser::UnidiffUtils->read_unidiff_text($fh, $filename, $revision, 0);push @result, @file_diffs;} else {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} = 0;push @result, $chunk;}# Read the next line.$line = <$fh>;}# Return the found diff chunks.return @result;}1;