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 VSS (Visual Source Safe) diffs.
10
 
11
package Codestriker::FileParser::VssDiff;
12
 
13
use strict;
14
use Codestriker::FileParser::BasicDiffUtils;
15
 
16
# Return the array of filenames, revision number, linenumber, whether its
17
# binary or not, and the diff text.
18
# Return () if the file can't be parsed, meaning it is in another format.
19
sub parse ($$$) {
20
    my ($type, $fh, $repository) = @_;
21
 
22
    # Array of results found.
23
    my @result = ();
24
 
25
    my $line = <$fh>;
26
    while (defined($line)) {
27
	# Values associated with the diff.
28
	my $revision;
29
	my $filename;
30
	my $repmatch;
31
 
32
	# Skip whitespace.
33
	while (defined($line) &&
34
	       ($line =~ /^\s*$/o || $line =~ /^Version not found/o)) {
35
	    $line = <$fh>;
36
	}
37
	return @result unless defined $line;
38
 
39
	# For VSS diffs, the start of the diff block is the "Diffing:" line
40
	# which contains the filename and version number.  Some diffs may
41
	# not contain the version number for us.
42
	if ($line =~ /^Diffing: (.*);(.+)$/o) {
43
	    $filename = $1;
44
	    $revision = $2;
45
	    $repmatch = 1;
46
	} elsif ($line =~ /^Diffing: (.*)$/o) {
47
	    $filename = $1;
48
	    $revision = $Codestriker::PATCH_REVISION;
49
	    $repmatch = 0;
50
	} else {
51
	    # Some other weird format.
52
	    return ();
53
	}
54
 
55
	# The next line will be the "Against:" line, followed by a blank line.
56
	$line = <$fh>;
57
	return () unless defined $line && $line =~ /^Against:/o;
58
	$line = <$fh>;
59
	return () unless defined $line && $line =~ /^\s*$/o;
60
 
61
	# The next part of the diff will be the old style diff format, or
62
	# possibly "No differences." if there are no differences.
63
	$line = <$fh>;
64
	if ($line !~ /^No differences\./o) {
65
	    my $chunk;
66
	    do
67
	    {
68
		my $leading_context = '';
69
		my $leading_context_line_count = 0;
70
		my $trailing_context = '';
71
		my $trailing_context_line_count = 0;
72
		if ($line =~ /^\*\*\*\*\*\*\*\*/o ||
73
		    $line =~ /^ /o) {
74
		    # Need to record some leading context.
75
		    $line = <$fh> if $line =~ /^\*\*\*\*\*\*\*\*/o;
76
		    while ($line =~ /^ (.*)$/o) {
77
			$leading_context .= "$1\n";
78
			$leading_context_line_count++;
79
			$line = <$fh>;
80
		    }
81
		}
82
 
83
		$chunk = Codestriker::FileParser::BasicDiffUtils
84
		    ->read_diff_text($fh, $line, $filename, $revision,
85
				     $repmatch);
86
		if (defined $chunk) {
87
		    # Check for trailing context.
88
		    $line = <$fh>;
89
		    while (defined $line && $line =~ /^ (.*)$/o) {
90
			$trailing_context .= "$1\n";
91
			$trailing_context_line_count++;
92
			$line = <$fh>;
93
		    }
94
 
95
		    # Adjust the chunk accordingly with the leading and
96
		    # trailing context.
97
		    if ($leading_context_line_count > 0) {
98
			$chunk->{old_linenumber} -= $leading_context_line_count;
99
			$chunk->{new_linenumber} -= $leading_context_line_count;
100
			$chunk->{text} = $leading_context . $chunk->{text};
101
		    }
102
		    if ($trailing_context_line_count > 0) {
103
			$chunk->{text} .= $trailing_context;
104
		    }
105
		    push @result, $chunk;
106
		}
107
	    } while (defined $chunk && defined $line);
108
	}
109
 
110
	# Read the next line.
111
	$line = <$fh> if defined $line;
112
    }
113
 
114
    # Return the found diff chunks.
115
    return @result;
116
}
117
 
118
1;