Subversion Repositories DevTools

Rev

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 ClearCase serial diff formats.
10
 
11
package Codestriker::FileParser::ClearCaseSerialDiff;
12
 
13
use strict;
14
use Codestriker::FileParser::BasicDiffUtils;
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, $repository) = @_;
20
 
21
    # Retrieve the repository root, and escape back-slashes in the case of
22
    # a Windows CVS repository, as it is used in regular expressions.
23
    my $repository_root =
24
	(defined $repository) ? $repository->getRoot() : undef;
25
    if (defined $repository_root) {
26
        $repository_root =~ s/\\/\\\\/g;
27
    }
28
 
29
    # Array of results found.
30
    my @result = ();
31
 
32
    # The current filename and revision being tracked.
33
    my $revision = $Codestriker::PATCH_REVISION;
34
    my $filename = "";
35
    my $repmatch = 0;
36
 
37
    # Ignore any whitespace at the start of the file.
38
    my $line = <$fh>;
39
    while (defined($line)) {
40
	# Skip any heading or trailing whitespace contained in the review
41
	# text, in addition to the "Files/Directories are identical" lines,
42
	# which happen due to the way review texts are generated.
43
	while (defined($line) &&
44
	       ($line =~ /^\s*$/o ||
45
		$line =~ /^Files are identical$/o ||
46
	        $line =~ /^Directories are identical$/o)) {
47
	    $line = <$fh>;
48
	}
49
	return @result unless defined $line;
50
 
51
	# Check if the next fileheader is being read.
52
	if (defined $line &&
53
	    $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o) {
54
 
55
	    # Now read the file/directory that has been modified.
56
	    $line = <$fh>;
57
	    return () unless defined $line;
58
 
59
	    if ($line =~ /^\<\<\< file 1\: (.*)\@\@(.*)$/o) {
60
		$filename = $1;
61
		$revision = $2;
62
 
63
		# Check if the filename matches the clear case repository.
64
		# This is very simple for now, but will need to be more
65
		# sophisticated later.
66
        if (defined $repository_root) {
67
            if ($filename =~ /^$repository_root[\/\\](.*)$/o) {
68
                $filename = $1;
69
            }
70
 
71
		    $repmatch = 1;
72
		} else {
73
		    $repmatch = 0;
74
		}
75
 
76
		# Read the next line which is the local file.
77
		$line = <$fh>;
78
		return () unless
79
		    defined $line && $line =~ /^\>\>\> file 2\: .*$/o;
80
 
81
		# Now expect the end of the file header.
82
		$line = <$fh>;
83
		return () unless
84
		    defined $line && $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o;
85
 
86
		# Read the next line.
87
		$line = <$fh>;
88
		return () unless defined $line;
89
	    }
90
	    elsif ($line =~ /^\<\<\< directory 1\: (.*)\@\@(.*)$/o) {
91
		# Currently we don't really support directory
92
		# operations.  ClearCase captures added/deleted
93
		# sub-directories and deleted files as a directory change,
94
		# but unfortunately added files go straight into the
95
		# VOB - great.  Try to fddge this so that we treat the
96
		# directory as a file, where the contents are the diff
97
		# file itself - better than nothing, and the reviewers
98
		# can at least see what is going on.
99
		$filename = $1;
100
		$revision = $2;
101
 
102
		# Check if the filename matches the clear case repository.
103
		# This is very simple for now, but will need to be more
104
		# sophisticated later.
105
		if (defined $repository_root &&
106
		    $filename =~ /^$repository_root[\/\\](.*)$/o) {
107
		    $filename = $1;
108
		}
109
 
110
		# Read the next line which is the local directory.
111
		$line = <$fh>;
112
		return () unless
113
		    defined $line && $line =~ /^\>\>\> directory 2\: .*$/o;
114
 
115
		# Now expect the end of the file header.
116
		$line = <$fh>;
117
		return () unless
118
		    defined $line && $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o;
119
 
120
		# Keep reading text until there is nothing left for this
121
		# segment.
122
		my $text = "";
123
		$line = <$fh>;
124
		while (defined $line &&
125
		       $line !~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o) {
126
		    if ($line !~ /^Files are identical$/o &&
127
			$line !~ /^Directories are identical$/o) {
128
			$text .= "+$line";
129
		    }
130
		    $line = <$fh>;
131
		}
132
 
133
		# Create the chunk, indicating there is not a repository match,
134
		# since this is for a directory entry with some basic text.
135
		my $chunk = {};
136
		$chunk->{filename} = $filename;
137
		$chunk->{revision} = $revision;
138
		$chunk->{old_linenumber} = 0;
139
		$chunk->{new_linenumber} = 1;
140
		$chunk->{binary} = 0;
141
		$chunk->{text} = $text;
142
		$chunk->{description} = "";
143
		$chunk->{repmatch} = 0;
144
		push @result, $chunk;
145
 
146
		# Process the next block.
147
		next;
148
	    }
149
	    else {
150
		# Some unknown format.
151
		return ();
152
	    }
153
	}
154
 
155
	# Read the next diff chunk.
156
	my $chunk =
157
	    Codestriker::FileParser::BasicDiffUtils->read_diff_text(
158
		       $fh, $line, $filename, $revision, $repmatch);
159
	return () unless defined $chunk;
160
	push @result, $chunk;
161
 
162
	# Read the next line.
163
	$line = <$fh>;
164
    }
165
 
166
    # Return the found diff chunks.
167
    return @result;
168
}
169
 
170
1;
171
 
172