#!/usr/bin/perl
# $Id: //depot/cad/tools/1.0/icp4/bin/p4ci#8 $
#
# CSWITCH CORPORATION CONFIDENTIAL PROPRIETARY
#
# This file contains information which is the
# proprietary property of Cswitch Corporation.
# This file is confidential and its contents may
# not be disclosed without the expressed written
# consent of Cswitch Corporation.
use strict;
use warnings;
use FindBin qw($Bin);
use lib "$Bin/../lib";
use Icp4;
use Getopt::Std;
use File::Basename;
our (%opt, $Program, $islayout);
our $attr_sfx = ".Ic_cell_template.attr";
our $cell_sfx = ".iccel_[0-9]+";
our $part_name = "part";
our $part_attr_sfx = ".Eddm_part.attr";
our $part_cell_sfx = ".part_[0-9]+";
our $sm_attr_sfx = ".mgc_symbol.attr";
our $sm_cell_sfx = ".smbl_[0-9]+";
our $sch_name = "sheet1";
our $sch_attr_sfx = ".mgc_sheet.attr";
our $sch_cell_sfx = ".(sgfx|ssht)_[0-9]+";
MAIN: {
my ($cell, $orig_cell, $cmd, $cells);
my ($attr_file, $orig_attr_file, $ic_pat);
my ($openStat, $expectedStat, $orig_cnt, $del_cmd);
my ($icfile, @allicfiles, @deletelist, $i);
my (@keep_list);
my ($part_attr, $part_pat);
my ($sm_attr, $sm_pat);
my ($sch_attr, $sch_pat);
$Program = $FindBin::Script;
getopts('hDnOrik:c:', \%opt);
if ($opt{h} || $#ARGV < 0) {
print "Usage: $Program [-h] [-n] [-r|-O|-c \"command\"] [-i] [-k num] cell+\n";
print " -h: help usage\n";
print " -n: show operation only\n";
print " -r: use unix remove instead of p4 delete\n";
print " (default: p4 delete)\n";
print " -O: use obliterate instead of p4 delete (requires p4 admin privileges)\n";
print " (default: p4 delete)\n";
print " -c: use custom command string instead of p4 delete\n";
print " (default: p4 delete)\n";
print " -i: ignore pending changes (dangerous!)\n";
print " -k: number of versions to keep\n";
print " (default: all files mentioned in the .attr file)\n";
print " cell: cell name(s)\n";
print " (hint: use \\\$ for cells with \$ character in their name)\n";
exit;
}
$Icp4::debug = ($opt{D}) ? 1 : 0 ;
$Icp4::nflag = ($opt{n}) ? 1 : 0 ;
$islayout = &Icp4::is_layout_view();
# TODO: support schematics
# if (! $islayout) {
# print "INFO: $Program only works from the layout.views directory for now. Exiting.\n";
# exit -1;
# }
if (!$opt{i} && &Icp4::outstanding_changes()) {
exit -1;
}
$cells = "";
foreach $cell (@ARGV) {
$orig_cell = $cell;
# escape the name for p4
if ($cell =~ /\$/) {
$cell =~ s/\$/\\\$/g;
print "# DEBUG: cell=$cell orig_cell=$orig_cell\n" if $opt{D};
}
if (-d $orig_cell) {
if ($islayout) {
# remove any .iclck files
unlink <$orig_cell/.*.iclck>;
#$cell_attr = $cell . $attr_sfx;
$ic_pat = $cell . $cell_sfx;
$orig_attr_file = "${orig_cell}/${orig_cell}${attr_sfx}";
$attr_file = "${cell}/${cell}${attr_sfx}";
if (! -f "$orig_attr_file") {
print "WARNING: $orig_attr_file not found. Trying the .s trick.\n";
$orig_attr_file = "${orig_cell}/${orig_cell}.s${attr_sfx}";
$attr_file = "${cell}/${cell}.s${attr_sfx}";
if (! -f "$orig_attr_file") {
print "WARNING: $orig_attr_file not found either. Skipping \"$orig_cell\".\n";
next;
} else {
print "INFO: Found alternate $orig_attr_file.\n";
}
}
p4tidy_proc($orig_cell, $attr_file, $orig_attr_file, $ic_pat, 1);
}
if (! $islayout) {
# part
$part_attr = "$cell/$part_name" . $part_attr_sfx;
$part_pat = $part_name . $part_cell_sfx;
if (-f "$part_attr") {
p4tidy_proc($cell, $part_attr, $part_attr, $part_pat, 1);
}
#symbol
$sm_attr = "$cell/$cell" . $sm_attr_sfx;
$sm_pat = $cell . $sm_cell_sfx;
if (-f "$sm_attr") {
p4tidy_proc($cell, $sm_attr, $sm_attr, $sm_pat, 1);
}
#schematic
$sch_attr = "$cell/schematic/$sch_name" . $sch_attr_sfx;
$sch_pat = $sch_name . $sch_cell_sfx;
if (-f "$sch_attr") {
p4tidy_proc("$cell/schematic", $sch_attr, $sch_attr, $sch_pat, 2);
}
}
}
}
exit 0;
}
sub p4tidy_proc {
my ($orig_cell, $attr_file, $orig_attr_file, $ic_pat, $mag_value) = @_;
my ($cmd);
my ($openStat, $expectedStat, $orig_cnt, $del_cmd);
my ($icfile, @allicfiles, @deletelist, $i);
my (@keep_list, $num_to_keep);
# ok, attr file exists
opendir CELLDIR, $orig_cell;
$openStat = &Icp4::openStat($attr_file);
$expectedStat = &Icp4::p4_stat_constant("NOT_OPENED");
if ($opt{D}) {
print "# DEBUG: \"$attr_file\" open stat=$openStat expected stat=$expectedStat\n";
}
if ($openStat == &Icp4::p4_stat_constant("UNKNOWN")) {
print "WARNING: File $attr_file not checked into p4 (code $openStat). Skipping.\n";
return;
}
if ($openStat != $expectedStat) {
print "WARNING: File $attr_file writable (code $openStat). Skipping.\n";
return;
}
#@keep_list = &Icp4::get_keep_list($orig_attr_file);
&Icp4::get_keep_list($orig_attr_file, \@keep_list);
if ($opt{D}) {
&Icp4::list_debug_print("keep_list", @keep_list);
}
if ($opt{k}) {
$orig_cnt = $#keep_list;
$num_to_keep = $opt{k} * $mag_value;
for ($i=0; $i <= ($orig_cnt - $num_to_keep ); $i++) {
shift @keep_list;
}
if ($opt{D}) {
print "# DEBUG: After trimming ... $#keep_list\n";
&Icp4::list_debug_print("keep_list", @keep_list);
}
}
@allicfiles = grep /$ic_pat/, readdir CELLDIR;
if ($opt{D}) {
&Icp4::list_debug_print("allicfiles", @allicfiles);
}
closedir CELLDIR;
@deletelist = @allicfiles;
foreach $icfile (@keep_list) {
# bad:
# @deletelist = grep !/^$icfile$/, @deletelist;
# good:
@deletelist = grep { $_ ne "$icfile" } @deletelist;
}
if ($opt{D}) {
&Icp4::list_debug_print("deletelist", @deletelist);
}
if ($opt{r}) {
$del_cmd = "/bin/rm -f";
} elsif ($opt{O}) {
$del_cmd = "p4 -y obliterate";
} elsif ($opt{c}) {
$del_cmd = $opt{c};
} else {
$del_cmd = "p4 delete";
}
foreach $i (@deletelist) {
$i =~ s/\$/\\\$/g;
$cmd = "$del_cmd $orig_cell/$i";
if ($opt{n}) {
print "INFO: (not run) $cmd\n";
} else {
print "INFO: Running $cmd\n";
system $cmd;
}
}
}