#!/usr/bin/perl # #******************************************************************************* # #Copyright (c) 2009, Perforce Software, Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #******************************************************************************* # #Author: Stephen Moon # #Date: August 11, 2010 #Last Modified: September 7, 2010 #Program: Generate an archive file using a file's p4 filelog with empty file # content. # #******************************************************************************* use warnings; use strict; use FileHandle; use File::Basename; sub headRevision() { my $fh = shift; my $lbrRev = shift; my @arrText = qw/head access symbols locks/; printf($fh "%-10s%-1s;\n",$arrText[0],$lbrRev); printf($fh "%-10s;\n",$arrText[1]); printf($fh "%-10s;\n",$arrText[2]); printf($fh "%-10s;comment @@;\n\n\n",$arrText[3]); return $lbrRev; } sub subRevision() { my $fh = shift; my $maxCount = shift; my $count = shift; my $regTokenRef = shift; my @arrText = qw/date author p4 state Exp branches next/; if($count >= 2) { printf($fh "%-10s%-1s;\n\n",$arrText[6],$regTokenRef->[1]); #index 1 = changelist } printf($fh "%-1s\n",$regTokenRef->[1]); #index 1 = changelist printf($fh "%-10s%-1s.%-1s.%-1s.",$arrText[0],$regTokenRef->[3], $regTokenRef->[4],$regTokenRef->[5]); printf($fh "%-1s.%-1s.%-1s; %-1s %-1s; %-1s %-1s;\n", $regTokenRef->[6],$regTokenRef->[7],$regTokenRef->[8],$arrText[1], $arrText[2],$arrText[3],$arrText[4]); printf($fh "%-10s;\n",$arrText[5]); #printf "max: $maxCount, ct: $count\n"; if($maxCount == $count) { printf($fh "%-10s;\n",$arrText[6]); } } sub revisionContent() { my $fh = shift; my $maxCount = shift; my $type = shift; my $revRef = shift; printf($fh "\n\ndesc\n@@\n\n\n"); #print "max: $maxCount\n"; for(0..$maxCount-1) { printf($fh "%-1s\nlog\n@@\n%-1s\n@@\n\n\n",$revRef->[$_],$type); } } sub getFstatInfo() { my $fstatRef = shift; my $p4 = shift; my $fileName = shift; # s option allows you to match "\n" with "." # m option allows you to match multiple lines with "^" and "$" my $depotFile = qr/^\.\.\. depotFile (.+)\n^\.\.\./sm; my $headTime = qr/clientFile.*^\.\.\. headTime (\d+)\n^\.\.\./sm; my $headRev = qr/headRev (\d+)\n.+^\.\.\./sm; my $lbrFile = qr/lbrFile (.+)\n^\.\.\./sm; my $lbrRev = qr/lbrRev (.+)\n^\.\.\./sm; my $lbrType = qr/lbrType (\S+)\n$/sm; $/ = ''; #sets input record separator to paragraph foreach(`$p4 fstat -Oc $fileName`) { if(/$depotFile $headTime $headRev $lbrFile $lbrRev $lbrType/) { print "$1, $2, $3, $4, $5, $6\n"; $fstatRef->{'lbrRev'} = $5; $fstatRef->{'lbrType'} = $6; if($1 eq $4) { print "Yes, they are the same: " . $1. " " . $4 . "\n"; $fstatRef->{'fileSame'} = 1; } else { print "No, they are different: " . $1. " " . $4 . "\n"; $fstatRef->{'fileSame'} = 0; } } } return $fstatRef; } sub main() { my $argc = @ARGV; if($argc != 1) { die "Usage: genLibrFile.pl \n"; } my $p4 = "p4 -u smoon -p 10.0.0.169:20101 -c smoon20101"; # For example: # ... #5 change 1017 edit on 2010/08/04 by smoon@smoon_ws (text) 'fifth revision' my $prefix = qr/^\.\.\. \#(\d+) change (\d+) (\w+) on/; my $date = qr/(\d{4})\/(\d{2})\/(\d{2})/; my $time = qr/(\d{2}):(\d{2}):(\d{2})/; my $cluser = qr/(\S+)\@(\S+)/; my $ftype = qr/\((\w+)\)/; my $description = qr/'(.*)'/; my $fileName = $ARGV[0]; my @regTokens = (); my @revArray = (); my $fstatRef = {}; my ($count,$maxCount,$fileSame) = (0,0,0); my $fh = new FileHandle; print "OS: $^O\n"; if($fileName =~ /^\/\/.*$/) { $fileName = basename($fileName); } $fh->open(">$fileName,v") or die "Unable to open $fileName,v\n"; #calculates the maximum revision count of the archive file foreach my $eachRev (`$p4 filelog -t $ARGV[0]`) { if($eachRev =~ /$prefix $date $time by $cluser $ftype $description.*$/) { $fstatRef = &getFstatInfo($fstatRef,$p4,"$fileName#$1"); if($fstatRef->{'fileSame'}) { $maxCount += 1; } } } $/ ="\n"; #sets the input record separator to linefeed foreach my $eachRev (`$p4 filelog -t $ARGV[0]`) { if($eachRev =~ /$prefix $date $time by $cluser $ftype $description.*$/) { $fstatRef = &getFstatInfo($fstatRef,$p4,"$ARGV[0]#$1"); if($fstatRef->{'fileSame'} != 1) { next; } else { $fileSame = 1; #Not a lazy copy } for(0..12) { if($_ == 1) { #print "rev token: $fstatRef->{'lbrRev'}\n"; $regTokens[$_] = $fstatRef->{'lbrRev'}; } elsif($_ == 11) { #print "rev token: $fstatRef->{'lbrType'}\n"; $regTokens[$_] = $fstatRef->{'lbrType'}; } else { $regTokens[$_] = eval("\$" . ($_ + 1)); #converts $1..$13 to matched tokens } } push(@revArray,$regTokens[1]); #index 1 is changelist number $count += 1; if($count == 1) { &headRevision($fh,$regTokens[1]); &subRevision($fh,$maxCount,$count,\@regTokens); } else{ &subRevision($fh,$maxCount,$count,\@regTokens); } } #end of regex conditional statement } #end of foreach loop if($fileSame) { &revisionContent($fh,$maxCount,$regTokens[11],\@revArray); # index 11 is filetype } close($fh); } #end of main &main();