#!/usr/bin/perl
# Branch engine for cdsp4
# Author: Shiv Sikand
open(DT,"date|") || die;
while(<DT>) {
$date=$_;
}
use Getopt::Long;
$Getopt::Long::autoabbrev=0; #make them specify exact option
unless($result=GetOptions("h",
"tp=s","block=s",
"user=s",
"lib=s",
"add=s",
"site=s",
"bname=s","from=s", "noint","force","lastchange=s")){
die "Illegal Input Options, -h for help\n";
}
$HELP="OPTION ERRORS\n";
$opt_top=1;
if($opt_block && $opt_top) {
die "Mutex block/top !!!!\n";
}
$opt_sp=$ENV{"PROJECT"};
print "Project is $opt_sp\n";
unless($opt_sp && $opt_tp && ( $opt_top || $opt_block || $opt_lib) && ($opt_bname || $opt_user)) {
print "$HELP\n";
exit;
}
if($opt_from && $opt_lastchange) {
print "from and lastchange are conflicting options !!\n";
exit;
}
if($opt_add && !$opt_bname) {
print "add requires the bname argument!!\n";
exit;
}
# Project specific variables
(@projparse)=split('/',$opt_sp);
# Derived chip and rev from $opt_sp
$chip=$projparse[$#projparse-1];
$rev=$projparse[$#projparse];
# Define cadence location within the tree
$libsubdir="layout/cadence";
$sourceproj=$opt_sp;
$targetproj=$opt_tp;
# Define cds.lib and cds.p4client locations
$cdslibsfile=$sourceproj."/$libsubdir/cds.lib";
$cdslibtfile=$targetproj."/$bdir"."/$libsubdir/cds.lib";
$cfile=$sourceproj."/$libsubdir/cds.p4client";
# Traling slashes can cause a big nightmare
# if they exist in one but not in the other
if(substr($opt_sp,-1,1) eq "/") {
print "ERROR: No trailing slashes allowed in sp or tp\n";
exit;
}
if(substr($opt_tp,-1,1) eq "/") {
print "ERROR: No trailing slashes allowed in sp or tp\n";
exit;
}
$user=$ENV{USER};
$block=$opt_block;
$ubname=$opt_bname;
if(!$ubname) {
@df=split(' ',$date);
$cnumspec="";
# build the branch spec
if($opt_block) {
if($opt_block eq "tapeout") {
$bname=$chip."_".$rev."_".$block."_".$df[1].$df[2]."_".$df[5];
} else {
$bname=$chip."_".$rev."_".$block."_".$df[1].$df[2]."_".$df[5]."_$opt_user";
}
}
elsif($opt_top) {
$bname=$chip."_".$rev."_top_".$df[1].$df[2]."_".$df[5]."_$opt_user";
}
elsif($opt_lib) {
$bname=$chip."_".$rev."_".$lib."_".$df[1].$df[2]."_".$df[5];
}
}
else {
$bname = $ubname;
}
# add the site based postfix
if(!$ubname && $opt_site) {
$bname=$bname."_".$opt_site;
}
if($opt_lastchange) {
print "\nBranch will be integrated to state at Change $opt_lastchange\n\n";
$cnumspec="@".$opt_lastchange;
}
if($opt_from) {
$bfname=$opt_from;
# get the file list for the client (excludes cds libs)
$bfclient=$bfname."_client";
#set up the names
if(!$opt_bname) {
(@bname2)=split('_',$opt_from);
$bname=$bname."_".$bname2[2];
# has the name got a month field instead of a year field at the end
# if so, it was a bob itself
# if that's the case we to contruct the complex name
# find everything after the year field
# and append it
(@bname3)=split(/_[0-9]+/,$opt_from);
if($bname3[1]) {
$bname=$bname.$bname3[1];
}
}
$newclient=$bname."_client";
if(!$opt_add) {
# get the non cds data
%flist=();
%flistl=();
&getfileparents($bfname,$bfclient,\%flist,\%flistl);
# assoc array flist contains list of files for non-cds data
# dump it to a file so we can use it with -x
open(BFILES1,">/tmp/bfilesmain.$$") || die;
foreach $key (sort(keys %flist)) {
print BFILES1 "$flist{$key}\n";
}
close(BFILES1);
# locally edited files need to be handled separately
if(%flistl) {
$dolocal=1;
open(BFILES2,">/tmp/bfilesmainl.$$") || die;
foreach $key (sort(keys %flistl)) {
print BFILES2 "$flistl{$key}\n";
}
close(BFILES2);
}
# Build a label to mark the files so we can easily integrate the label's contents
$lname=$bfname."label";
$cmd="p4 label -o $lname | p4 label -i > /dev/null";
system($cmd);
# sync the label to the file list
print "Syncing to label for mainline files\n";
$cmd="p4 -c $bfclient -x /tmp/bfilesmain.$$ labelsync -a -l $lname >> /tmp/bflsync.$$ 2>&1";
system($cmd);
#set up the integration command
$int_cmd="p4 -c $newclient integrate //depot/...@".$lname." //depot/$bname/...";
# Do the same (similar) for local files
if($dolocal) {
$lnamel=$bfname."label_local";
$cmd="p4 label -o $lnamel | p4 label -i ";
system($cmd);
# sync the label to the file list
print "Syncing to label for local files\n";
$cmd="p4 -c $bfclient -x /tmp/bfilesmainl.$$ labelsync -a -l $lnamel >> /tmp/bflsyncl.$$ 2>&1";
system($cmd);
# create the crossbranch spec
$crossbranch="cb".$bfrom.$bname;
$cmd="p4 branch -o $crossbranch | p4 branch -i > /dev/null";
system($cmd);
# fix the view
$cmd="p4 branch -o $crossbranch | sed 's/\\/\\/depot\\/\\.\\.\\. \\/\\/depot\\/\\.\\.\\./\\/\\/depot\\/$bfname\\/\\.\\.\\. \\/\\/depot\\/$bname\\/\\.\\.\\./g' | p4 branch -i > /dev/null";
system($cmd);
#set up the integration command
$int_cmd2="p4 -c $newclient integrate -b $crossbranch //depot/...\@".$lnamel;
}
}
}
print "\nSource project is $sourceproj\n";
if($opt_block) {
$branchdes=$opt_block;
}
else {
if($opt_top) {
$branchdes="top";
} else {
$branchdes=$opt_lib;
}
}
# Build the branches
if($bname eq "") {
die "Null bname!";
}
if($opt_add) {
print "Updating $bname to include $opt_add\n";
$newclient=$bname."_client";
print "$newclient\n";
} else {
if(!$opt_from2) {
# Get the refclient spec
$refclient=$chip."_".$rev."_ref_".$branchdes;
# Check to see if it exists
$cmd="p4 clients | grep $refclient > /dev/null";
system($cmd);
# Good exit means it exists
if ($? ne 0) {
print "Couldn't find $refclient, aborting\n";
exit(1);
}
$cmd="p4 client -o $refclient | grep \"^\t//\*\" ";
$bstring="Branch: $bname\nDescription: $branchdes $chip $rev (by $user)\nView:\n";
# This gives us the LHS view mappings
open(CMD, "$cmd|") || die ;
while(<CMD>) {
chop;
(@ddata)=split;
$rhs=$ddata[0];
$rhs =~ s/$chip\/$rev/$bname/g;
$dstring="\t$ddata[0] $rhs\n";
$bstring=$bstring.$dstring;
}
$cmd="echo \"$bstring\" > /tmp/bspec; p4 branch -i < /tmp/bspec";
system($cmd);
}
else {
die("Cloning not supported\n");
# Clone named branch
if(!$ubname) {
$bname=$opt_from2."_".$df[1].$df[2];
}
else {
$bname=$ubname;
}
print "Target project is $targetproj/$bname\n\n";
print "Building branch $bname from $opt_from2\n";
die("Broken");
$cmd="echo \"Branch: $bname\nDescription: $branchdes sub branch built by $user\nView:\n\t//depot/$chip/$rev/$opt_from2/layout/blocks/$block/cadence/$block/... //depot/$bname/layout/blocks/$block/cadence/$block/...\n\t//depot/layout/reference/*/cadence/... //depot/$bname/layout/reference/*/cadence/...\"> /tmp/bspec; p4 branch -i < /tmp/bspec > /dev/null";
system($cmd);
}
# build a client
# clone the main gfxdesign view spec
$newclient=$bname."_client";
if(!$opt_from2) {
#$refclient=$chip."_ref_".$branchdes;
$refclient=$chip."_".$rev."_ref_".$branchdes;
} else {
$refclient=$opt_from2."_client";
}
# Make client building a subroutine with nocds flag
if($opt_top) {
&buildclient($refclient,$newclient,$sourceproj,$targetproj,1,1);
}
else {
&buildclient($refclient,$newclient,$sourceproj,$targetproj,1,0);
}
if( !$opt_noint) {
# Integrate the new branch
print "Integrating the branch\n";
if(!$int_cmd) {
$int_cmd="p4 -c $newclient integrate -v -b $bname $cnumspec";
}
print "\n$int_cmd\n\n";
system($int_cmd);
if($int_cmd2) {
print "\n$int_cmd2\n\n";
system($int_cmd2);
}
if($opt_from) {
# delete the temp label
$cmd="p4 label -d $lname";
system($cmd);
$cmd="p4 label -d $lnamel";
system($cmd);
}
# Submit the branch
$cmd="p4 -c $newclient change -o | sed 's/<.*>/Branch submit by buildbranch/' > /tmp/subout.$$";
system($cmd);
open(SUB, "</tmp/subout.$$") || die "Couldn't read change description\n";
$submit=0;
while(<SUB>) {
if(/^Files/) {
$submit++;
close(SUB);
}
}
if($submit) {
$cmd="p4 -c $newclient submit -i < /tmp/subout.$$";
system($cmd);
}
}
# Rebuild the client correctly
#&buildclient($refclient,$newclient,$sourceproj,$targetproj,0);
# Fake sync the client to update the files
#$cmd="p4 -c $newclient flush";
#system($cmd);
# Delete newclient if mode layout since it's now empty
}
if($opt_nocds) {
exit;
}
$bdir="$bname";
# Build Cadence library clients
print "\nBuilding Cadence library clients\n";
$cdslibsfile=$sourceproj."/$libsubdir/cds.lib";
if($opt_block eq "tapeout") {
$cdslibtfile=$targetproj."/$libsubdir/cds.lib";
} else {
$cdslibtfile=$targetproj."/$bdir"."/$libsubdir/cds.lib";
}
$p4 = "p4";
open(CFILE, "<$cfile") || die "Couldn't read $cfile\n";
print "Reading $cfile\n";
while(<CFILE>) {
if(/^\#/) {
next;
}
chop;
(@cdata)=split;
$path=$cdata[1];
$client=$cdata[2];
(@cinfo)=split(':',$cdata[2]);
#$client2=$cinfo[0].":".$cinfo[1];
$client2=$cinfo[0];
# Read the client spec so that we can clone it
# Only clone libraries that are in the branch spec!!
if($opt_add) {
if($client =~ /$opt_add/) {
$vclient{$client}=$client2;
print "Accepting requested client $client\n";
close(CFILE);
}
}
if(!$opt_add) {
if(!$opt_top) {
$match=$blocklib.":".$chip."_".$rev;
# Accept this blocks libraries or reference libs only
if($client =~ /$match/ || $path =~ /reference/) {
#print "Acepting client $client\n";
$vclient{$client}=$client2;
}
} else {
# Accept all clients since it's a top level build
print "Acepting client $client\n";
$vclient{$client}=$client2;
}
}
}
foreach $client (keys %vclient) {
$client2=$vclient{$client};
$cmd="p4 -c $client client -o";
open(CMD, "$cmd|") || die ;
open(CMDOUT, ">/tmp/cbout") || die ;
while(<CMD>) {
if(/^Options/) {
# Modtime is nice for sorting in lbb
s/nomodtime/modtime/g;
if($opt_site) {
s/nocompress/compress/g;
}
print CMDOUT $_;
}
if(/^Client/) {
print CMDOUT "Client: $client2:$bdir\n\n";
}
if(/^Description/) {
print CMDOUT "Description:\n\tcds library\n\n";
}
if(/^Root/) {
# Add the branch spec to the root
# where's a perl manual when you need one
$swap=0;
if($opt_block eq "tapeout") {
$newroot=$targetproj;
} else {
$newroot=$targetproj."/".$bdir;
}
$swap = s/$sourceproj/$newroot/g ;
#s/$sourceproj/$newroot/g ;
if($swap eq 1) {
print CMDOUT "$_\n";
}
else {
print "Failed to map root for client $client\n$_\n";
print "Check your -sp flag!\n";
exit;
}
}
if(/^View/) {
print CMDOUT "$_\n";
}
# BOB depot spec has extra component that we need to skip
if(/^\t\-{0,1}\/\/depot/) {
if(!($opt_from || $opt_from2)) {
$newdepot="depot/".$bdir;
# New LHS
s/depot\/$chip\/$rev/$newdepot/g ;
#print "$_\n";
# New RHS
# Everything before the colon
# eg aq:n1 becomes aq:n1_aq_Oct7_1999
$newcdsclient=$client2.":".$bdir ;
s/$client/$newcdsclient/g;
print CMDOUT $_;
} else {
if($opt_from) {
$newdepot="depot/".$bdir;
s/$opt_from\///;
s/depot\/$chip\/$rev/$newdepot/g ;
# New RHS
$newcdsclient=$client2.":".$bdir ;
s/$client/$newcdsclient/g;
print CMDOUT $_;
}
if($opt_from2) {
$newdepot="depot/".$bdir;
s/$opt_from2\///;
s/depot\/$chip\/$rev/$newdepot/g ;
# New RHS
$newcdsclient=$client2.":".$bdir ;
s/$client/$newcdsclient/g;
print CMDOUT $_;
}
}
}
}
close(CMDOUT);
#print "Building client $newcdsclient\n";
$cmd=$p4." -c $newcdsclient client -i < /tmp/cbout > /dev/null";
system($cmd);
# integrate the cadence libraries
# since we don't allow overlapping clients
# and need to set up the right state for a
# Fast integrate using -v
# These should already be integrated at branch build time
#if( !$opt_noint && !$opt_from && !opt_add) {
# $cmd="p4 -c $newcdsclient integrate -v -b $bname $cnumspec";
# print "$cmd\n";
# system($cmd);
#}
if($opt_from) {
# Do the same thing that we did earlier to build a file set
%flist=();
%flistl=();
$cdsname=$client.":".$bfname;
&getfileparents($bfname,$cdsname,\%flist,\%flistl);
# assoc array flist contains list of files for non-cds data
# dump it to a file so we can use it with -x
if(%flist) {
open(BFILES1,">/tmp/bfilecds.$newcdsclient.$$") || die;
foreach $key (sort(keys %flist)) {
print BFILES1 "$flist{$key}\n";
}
close(BFILES1);
}
if(%flistl) {
open(BFILES2,">/tmp/bfilecdsl.$newcdsclient.$$") || die;
foreach $key (sort(keys %flistl)) {
print BFILES2 "$flistl{$key}\n";
}
close(BFILES2);
}
if(%flist) {
# Build a label to mark the files so we can easily integrate the label's contents
$lname=$newcdsclient."label";
$cmd="p4 label -o $lname | p4 label -i > /dev/null";
system($cmd);
# sync the label to the file list
$cmd="p4 -c $newcdsclient -x /tmp/bfilecds.$newcdsclient.$$ labelsync -a -l $lname> /tmp/bflsync.$$ 2>&1";
system($cmd);
#set up the integration command
print "INTEGRATING mainline\n";
$int_cmd="p4 -c $newcdsclient integrate //depot/...@".$lname." //depot/$bname/...";
print "\n$int_cmd\n\n";
system($int_cmd);
$cmd="p4 label -d $lname";
system($cmd);
}
# Do the same for the locals
if(%flistl) {
$lnamel=$newcdsclient."label_local";
$cmd="p4 label -o $lnamel | p4 label -i > /dev/null";
system($cmd);
# sync the label to the file list
$cmd="p4 -c $newcdsclient -x /tmp/bfilecdsl.$newcdsclient.$$ labelsync -a -l $lnamel > /tmp/bflsyncl.$$ 2>&1";
system($cmd);
#set up the integration command
print "INTEGRATING local edits\n";
$int_cmd="p4 -c $newcdsclient integrate -b $crossbranch //depot/...\@".$lnamel;
print "\n$int_cmd\n\n";
system($int_cmd);
$cmd="p4 label -d $lnamel";
system($cmd);
}
}
#Manual submit
# But don't submit empty files
$cmd="p4 -c $newcdsclient change -o | sed 's/<.*>/Branch submit by buildbranch/' > /tmp/subout.$$";
system($cmd);
open(SUB, "</tmp/subout.$$") || die "Couldn't read change description\n";
$submit=0;
while(<SUB>) {
if(/^Files/) {
$submit++;
close(SUB);
}
}
if($submit) {
$cmd="p4 -c $newcdsclient submit -i < /tmp/subout.$$";
system($cmd);
}
# Now sync to bring in the files
if($opt_force) {
$cmd="p4 -c $newcdsclient sync -f";
} else {
if(!$opt_add) {
if(!$opt_noint) {
#print "Syncing client $newcdsclient\n";
$cmd="p4 -c $newcdsclient sync";
} else {
$cmd="p4 -c $newcdsclient sync -n";
}
} else {
# bring in the new data
$cmd="p4 -c $newcdsclient integrate -v -b $bname\n";
}
}
# Need to read stderror for the error
print "Int cmd is $cmd\n";
open(CMD, "$cmd 2>&1 |") || die "Couldn't do an integrate....\n";
while(<CMD>) {
if(/No such file/) {
# Delete the client, it's not valid
print "ERROR: $newcdsclient does not contain any data\n";
print "ERROR: If this is expected, please use the -skip option\n";
print "ERROR: Or integrate this library explicitly by typing\n";
print "p4 -c $newclient integrate -b $bname\n";
print "Then run this script again with the -add option\n";
}
}
}
close(CFILE);
#Manual submit
# But don't submit empty files
$cmd="p4 -c $newcdsclient change -o | sed 's/<.*>/Branch submit by buildbranch/' > /tmp/subout.$$";
system($cmd);
open(SUB, "</tmp/subout.$$") || die "Couldn't read change description\n";
$submit=0;
while(<SUB>) {
if(/^Files/) {
$submit++;
close(SUB);
}
}
if($submit) {
$cmd="p4 -c $newcdsclient submit -i < /tmp/subout.$$";
system($cmd);
}
# write the master client file
# branch may not have all the chip clients that match this grep spec
$cmd="$p4 clients | grep 'cds library' | grep '$bdir ' > /tmp/client";
system($cmd);
open(CDATA, "</tmp/client") || die ;
if($opt_block eq "tapeout") {
$cfile=$targetproj."/$libsubdir/cds.p4client";
} else {
$cfile=$targetproj."/".$bdir."/$libsubdir/cds.p4client";
}
open(CDOUT, ">$cfile") || die "Couldn't write $cfile\n";
print "Writing $cfile\n";
if(!$opt_add) {
print CDOUT "# Master Client file for $targetproj/$bdir\n# Built by buildbranch $date";
}
while(<CDATA>) {
@cdata=split;
# Key it on the root
$cdslist{$cdata[4]}=$cdata[1];
(@lib)=split('/',$cdata[4]);
# Last element in path is lib name
$libname=$lib[($#)-1];
#print "LIB: $libname PATH:$cdata[4] CLIENT: $cdata[1]\n";
print CDOUT "$libname $cdata[4] $cdata[1]\n";
}
if($opt_add) {
print "Updating branch cds.lib file\n";
}
else {
print "Building branch cds.lib file\n";
}
# Unamanaged in trex
#$cmd="p4 -c $newclient edit $cdslibtfile";
#system($cmd);
# Process it !
open(CDSL, "<$cdslibsfile") || die "Couldn't read $cdslibsfile!\n";
if($opt_add) {
open(CDSLB, ">>$cdslibtfile") || die "Couldn't open $cdslibtfile!\n";
} else {
open(CDSLB, ">$cdslibtfile") || die "Couldn't open $cdslibtfile!\n";
}
if(!$opt_add) {
print CDSLB "-- File Created by buildbranch $date\n";
}
$client=0;
while(<CDSL>) {
$match=0;
if($opt_add) {
if(!(/ $opt_add /)) {
next;
}
}
if( /^DEFINE/ || /^INCLUDE/) {
$save=$_;
($ig,$libname,$path)=split;
if($opt_add) {
if(!(/ $opt_add /)) {
next;
}
}
$newproj=$targetproj."/$bdir";
# only map out the library if it is p4 controlled
# since it won't exist in the branch otherwise
$gotc=0;
$bpath=$path;
$bpath=~ s/$sourceproj/$newproj/g;
if($client=$cdslist{$bpath}) {
$gotc++;
}
# handle basic library
# bring it in exactly as defined !
if(/INCLUDE/) {
print "Bringing in $_\n";
print CDSLB $_;
next;
}
if($gotc) {
$client=$save;
s/$sourceproj/$newproj/g;
# Check to see if the directory exists
# since it may not have been branched
$copy=$_;
(@elements)=split(' ',$copy);
$cmd="ls -d $elements[2] >>/dev/null 2>&1";
#print "$cmd\n";
system($cmd);
if($? ne 0) {
print "Skipping unbranched lib: $elements[1]\n";
next;
}
print "Mapping $libname in branch cds.lib\n";
print CDSLB $_;
}
else {
# bring in non-managed libs directly as references to mainline
# except for rams
if(!( $save =~ /$chip_ram/)) {
print "Writing $libname in branch cds.lib file\n";
print CDSLB $save;
}
}
}
else {
if(/ \./) {
print "Couldn't map dot in $_\n";
exit;
}
print CDSLB $_;
}
}
close(CDSLB);
close(CDSL);
unlink("/tmp/cbout");
unlink("/tmp/client");
if($opt_from) {
system("rm /tmp/bf*.$$");
}
# delete crossbranch
if($crossbranch) {
$cmd="p4 branch -d $crossbranch";
system($cmd);
}
# delete main labels ????
sub buildclient {
my($refclient,$newclient,$sourceproj,$targetproj,$nominus,$top)=@_;
print "Reading reference client $refclient\n";
#Check to see if it really exists
# Check to see if it exists
$cmd="p4 clients | grep $refclient";
system($cmd);
# Good exit means it exists
if ($? ne 0) {
print "Couldn't find it, aborting\n";
exit(1);
}
print "Newclient is $newclient\n";
$cmd="p4 -c $refclient client -o";
open(CMD, "$cmd|") || die ;
open(CMDOUT, ">/tmp/cbout") || die ;
while(<CMD>) {
# Enable site compression
if($opt_site) {
if(/nocompress/) {
s/nocompress/compress/g;
print CMDOUT "$_\n";
}
}
if(/^Client/) {
print CMDOUT "Client: $newclient\n\n";
}
if(/^Description/) {
print CMDOUT "Description: client for $bname $df[0] $df[1] $df[2] $df[5] built by $user\n";
}
if(/^Root/) {
if($opt_block eq "tapeout") {
$root=$targetproj;
} else {
$root=$targetproj."/".$bname;
}
print CMDOUT "Root: $root\n";
}
if(/^View/) {
print CMDOUT "$_\n";
}
if(/^\t\-{0,1}\/\/depot/) {
if(!$opt_from2) {
$newdepot="depot/".$bname;
# New LHS
s/depot\/$chip\/$rev/$newdepot/g ;
} else {
$newdepot="depot/".$bname;
s/$opt_from2\///g;
s/depot\/$chip\/$rev/$newdepot/g ;
}
# New RHS
s/$refclient/$newclient/g;
# Skip the minus
# to make sure that minus lines get branched
# even though we want them (the minus signs) in the client after
# branching is complete
# to prevent overlapping Cadence library clients
# are you following me ?
if($nominus eq "1") {
if(/^\t\-/) {
s/\-//g;
}
}
print CMDOUT $_;
}
}
close(CMDOUT);
print "Building $newclient from $refclient\n";
$cmd="p4 -c $newclient client -i < /tmp/cbout > /dev/null";
system($cmd);
}
sub getfileparents {
if($opt_noint) {
return;
}
# Minimise the number of system calls so use lots of files
# and pass to p4 using -x option
my($branch,$client,$flist,$flistl)=@_;
my($cmd);
print "\nGetting file list for $client\n";
$cmd="p4 files //depot/".$branch."/...@".$client.">/tmp/bfiles.$$";
system($cmd);
# get branch and integrate files
# since they (most likely) came from the mainline
# TODO: TRAP if they didn't here or later
$cmd="grep '\\- branch change' /tmp/bfiles.$$ > /tmp/bfilesib.$$";
system($cmd);
$cmd="grep '\\- integrate change' /tmp/bfiles.$$ >> /tmp/bfilesib.$$";
system($cmd);
$cmd="grep -v '\\- integrate change' /tmp/bfiles.$$ > /tmp/bfilesnib.$$";
system($cmd);
$cmd="grep -v '\\- branch change' /tmp/bfilesnib.$$ > /tmp/bfileslocal.$$";
system($cmd);
#print "Generating integrated file list\n";
&genlist("/tmp/bfilesib.$$",\%$flist,\%$flistl,"ib");
#print "Generating local file list\n";
&genlist("/tmp/bfileslocal.$$",\%$flist,\%$flistl,"local");
}
sub genlist {
my($infile,$flist,$flistl,$faction)=@_;
my($cmd,$record,$checkri,$catchver,@vinfo,$index,$count);
my($version,$action,$dfv,@dinfo,$ldf,$getver,$pversion,@pdata,@copydata);
# read the file list and produce a list to pass to filelog
# but stash the version numbers in an array so we can pull
# out the right data from the filelog
open(FLISTF, ">/tmp/bflist.$$") || die;
open(INFILEF, "< $infile") || die ;
while(<INFILEF>) {
(@fdata)=split;
$dfv=$fdata[0];
(@dinfo)=split('#',$dfv);
$df=$dinfo[0];
$version=$dinfo[1];
$action=$fdata[2];
print FLISTF "$df\n";
push(@vinfo,$version);
}
close(FLISTF);
close(INFILEF);
$cmd="p4 -x /tmp/bflist.$$ filelog >/tmp/bflog.$$";
system($cmd);
open(CMD, "</tmp/bflog.$$") || die;
$record=0;
# reverse integrate check
$checkri=1;
$catchver=0;
$index=0;
while(<CMD>) {
chop;
if( (/^\/\/depot/ || eof) && $record && $faction eq "local") {
$ldf=$depot."#".$getver;
#print "FLISTL $ldf\n";
$$flistl{$depot}=$ldf;
$record=0;
$catchver=0;
$index++;
}
# if a branch back/from record could not be found treat as local edit
if( /^\/\/depot/ && $record && $faction eq "ib") {
$ldf=$depot."#".$getver;
$$flistl{$depot}=$ldf;
$record=0;
$catchver=0;
$index++;
}
# New depot file record begins here
if( /^\/\/depot/ && !$record) {
$depot=$_;
$catchver=1;
$checkri=1;
}
$getver=$vinfo[$index];
# Got a new record, make sure we catch the right version
# $record now signifies that we are ready to process the info
if(/\.\.\. \#$getver/ && $catchver) {
$record=1;
}
# Look for branch into info if in local mode
# if we find it, reset counter so we can find next valid record
if(/\.\.\. \.\.\. [a-z]+ into \/\/depot\/BALI/ && $record && $faction eq "local") {
(@copydata)=split;
$count++;
(@pdata)=split('#',$copydata[4]);
# eliminate #1,#4 style syntax ( ie we want #4)
$pversion=$pdata[0]."#".$pdata[$#pdata];
#print "K $pdata[0]\n";
$$flist{$pdata[0]}=$pversion;
$checkri=0;
$record=0;
$catchver=0;
$index++;
}
#if we didn't find a branch into record, it was a local edit
if(/\.\.\. \.\.\. [a-z]+ from/ && $record && $faction eq "ib" && !/gfx_$chip/) {
# may not have been branched from mainline
(@copydata)=split;
$count++;
#print "$count $pversion\n";
(@pdata)=split('#',$copydata[4]);
# eliminate #1,#4 style syntax ( ie we want #4)
$pversion=$pdata[0]."#".$pdata[$#pdata];
#print "Pushing $pversion\n";
$$flist{$pdata[0]}=$pversion;
$record=0;
$catchver=0;
$index++;
}
}
close(OFILE);
}
# interrupt signal handler
sub handler {
my $sig = @_;
$SIG{'INT'} = 'IGNORE'; # ignore SIGINT
warn "Caught a SIG$sig--shutting down\n";
exit();
}