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 ClearCase serial diff formats.package Codestriker::FileParser::ClearCaseSerialDiff;use strict;use Codestriker::FileParser::BasicDiffUtils;# 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, $repository) = @_;# Retrieve the repository root, and escape back-slashes in the case of# a Windows CVS repository, as it is used in regular expressions.my $repository_root =(defined $repository) ? $repository->getRoot() : undef;if (defined $repository_root) {$repository_root =~ s/\\/\\\\/g;}# Array of results found.my @result = ();# The current filename and revision being tracked.my $revision = $Codestriker::PATCH_REVISION;my $filename = "";my $repmatch = 0;# Ignore any whitespace at the start of the file.my $line = <$fh>;while (defined($line)) {# Skip any heading or trailing whitespace contained in the review# text, in addition to the "Files/Directories are identical" lines,# which happen due to the way review texts are generated.while (defined($line) &&($line =~ /^\s*$/o ||$line =~ /^Files are identical$/o ||$line =~ /^Directories are identical$/o)) {$line = <$fh>;}return @result unless defined $line;# Check if the next fileheader is being read.if (defined $line &&$line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o) {# Now read the file/directory that has been modified.$line = <$fh>;return () unless defined $line;if ($line =~ /^\<\<\< file 1\: (.*)\@\@(.*)$/o) {$filename = $1;$revision = $2;# Check if the filename matches the clear case repository.# This is very simple for now, but will need to be more# sophisticated later.if (defined $repository_root) {if ($filename =~ /^$repository_root[\/\\](.*)$/o) {$filename = $1;}$repmatch = 1;} else {$repmatch = 0;}# Read the next line which is the local file.$line = <$fh>;return () unlessdefined $line && $line =~ /^\>\>\> file 2\: .*$/o;# Now expect the end of the file header.$line = <$fh>;return () unlessdefined $line && $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o;# Read the next line.$line = <$fh>;return () unless defined $line;}elsif ($line =~ /^\<\<\< directory 1\: (.*)\@\@(.*)$/o) {# Currently we don't really support directory# operations. ClearCase captures added/deleted# sub-directories and deleted files as a directory change,# but unfortunately added files go straight into the# VOB - great. Try to fddge this so that we treat the# directory as a file, where the contents are the diff# file itself - better than nothing, and the reviewers# can at least see what is going on.$filename = $1;$revision = $2;# Check if the filename matches the clear case repository.# This is very simple for now, but will need to be more# sophisticated later.if (defined $repository_root &&$filename =~ /^$repository_root[\/\\](.*)$/o) {$filename = $1;}# Read the next line which is the local directory.$line = <$fh>;return () unlessdefined $line && $line =~ /^\>\>\> directory 2\: .*$/o;# Now expect the end of the file header.$line = <$fh>;return () unlessdefined $line && $line =~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o;# Keep reading text until there is nothing left for this# segment.my $text = "";$line = <$fh>;while (defined $line &&$line !~ /^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*$/o) {if ($line !~ /^Files are identical$/o &&$line !~ /^Directories are identical$/o) {$text .= "+$line";}$line = <$fh>;}# Create the chunk, indicating there is not a repository match,# since this is for a directory entry with some basic text.my $chunk = {};$chunk->{filename} = $filename;$chunk->{revision} = $revision;$chunk->{old_linenumber} = 0;$chunk->{new_linenumber} = 1;$chunk->{binary} = 0;$chunk->{text} = $text;$chunk->{description} = "";$chunk->{repmatch} = 0;push @result, $chunk;# Process the next block.next;}else {# Some unknown format.return ();}}# Read the next diff chunk.my $chunk =Codestriker::FileParser::BasicDiffUtils->read_diff_text($fh, $line, $filename, $revision, $repmatch);return () unless defined $chunk;push @result, $chunk;# Read the next line.$line = <$fh>;}# Return the found diff chunks.return @result;}1;