Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1293 dpurdie 1
###############################################################################
2
# Codestriker: Copyright (c) 2001, 2002, 2003 David Sitsky.
3
# All rights reserved.
4
# sits@users.sourceforge.net
5
#
6
# This program is free software; you can redistribute it and modify it under
7
# the terms of the GPL.
8
 
9
# Parser object for reading patch unidiffs.
10
 
11
package Codestriker::FileParser::PatchUnidiff;
12
 
13
use strict;
14
use Codestriker::FileParser::UnidiffUtils;
15
 
16
# Return the array of filenames, revision number, linenumber and the diff text.
17
# Return () if the file can't be parsed, meaning it is in another format.
18
sub parse ($$) {
19
    my ($type, $fh) = @_;
20
 
21
    # Array of results found.
22
    my @result = ();
23
 
24
    # Ignore any whitespace at the start of the file.
25
    my $line = <$fh>;
26
    while (defined($line)) {
27
 
28
	# Values associated with the diff.
29
	my $revision = $Codestriker::PATCH_REVISION;
30
	my $filename = "";
31
	my $old_linenumber = -1;
32
	my $new_linenumber = -1;
33
	my $binary = 0;
34
 
35
	# Skip any heading or trailing whitespace contained in the review
36
	# text.
37
	while (defined($line) && $line =~ /^\s*$/) {
38
	    $line = <$fh>;
39
	}
40
	return @result unless defined $line;
41
 
42
	# For unidiffs, the diff line may appear first, but is optional,
43
	# depending on how the diff was generated.  In any case, the line
44
	# is ignored.
45
	if (defined $line && $line =~ /^diff/o) {
46
	    $line = <$fh>;
47
	}
48
	return () unless defined $line;
49
 
50
        # Need to check for binary file differences.
51
        # Unfortunately, when you provide the "-N" argument to diff,
52
        # it doesn't indicate new files or removed files properly.  Without
53
        # the -N argument, it then indicates "Only in ...".
54
        if ($line =~ /^Binary files .* and (.*) differ$/ ||
55
	    $line =~ /^Files .* and (.*) differ$/) {
56
            $filename = $1;
57
            $binary = 1;
58
        } elsif ($line =~ /^Only in (.*): (.*)$/) {
59
            $filename = "$1/$2";
60
            $binary = 1;
61
	} elsif ($line =~ /^\-\-\- \/dev\/null/o) {
62
	    # File has been added.
63
	    $revision = $Codestriker::ADDED_REVISION;
64
	} elsif ($line =~ /^\-\-\- (.*)\t/o) {
65
	    $filename = $1;
66
	} else {
67
	    return ();
68
	}
69
 
70
	if ($binary == 0) {
71
	    # Now expect the +++ line.
72
	    $line = <$fh>;
73
	    return () unless defined $line;
74
 
75
	    # Check if it is a removed file.
76
	    if ($line =~ /^\+\+\+ \/dev\/null/o) {
77
		# File has been removed.
78
		$revision = $Codestriker::REMOVED_REVISION;
79
	    } elsif ($line =~ /^\+\+\+ (.*)\t/o) {
80
		$filename = $1;
81
	    } else {
82
		return ();
83
	    }
84
 
85
	    # Extract the diff chunks for this file.
86
	    my @file_diffs = Codestriker::FileParser::UnidiffUtils->
87
		read_unidiff_text($fh, $filename, $revision, 0);
88
	    push @result, @file_diffs;
89
	} else {
90
	    my $chunk = {};
91
	    $chunk->{filename} = $filename;
92
	    $chunk->{revision} = $revision;
93
	    $chunk->{old_linenumber} = -1;
94
	    $chunk->{new_linenumber} = -1;
95
	    $chunk->{binary} = 1;
96
	    $chunk->{text} = "";
97
	    $chunk->{description} = "";
98
	    $chunk->{repmatch} = 0;
99
	    push @result, $chunk;
100
	}
101
 
102
	# Read the next line.
103
	$line = <$fh>;
104
    }
105
 
106
    # Return the found diff chunks.
107
    return @result;
108
}
109
 
110
1;
111
 
112