#!/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; } } }