0

The example input tcl file content:

# Bind
 ::d::autoBindmap $intfcName 

-------------so many other lines------------------------------
############ Power information for vss #####################
#----------------------------
 #pg_vss s100
#----------------------------
 #Add pg_vss_dl interface
set  intfcName pg_vss 1.0 s 100

 #Add Verilog port binding for vss
 ::d::autoBindmap $module pg_vss $intfcName
{
 VSSGND vss_dl;
 }

############ Power information for vdd #####################
#----------------------------
 #pg_vdd s100
#----------------------------
 #Add pg_vdd_dl interface
set  intfcName pg_vdd 1.0 s 100

 #Add Verilog port binding for vss
 ::d::autoBindmap $module pg_vdd $intfcName
{
 VDD vss_dl;
 }

-----------------------so many other lines-------------------------------

 #write component 
 ::d::writeLib $module

Purpose: I have an array (which is generated from other part of code not presented here) consisting of strings. The array content is changing for different files. If any of the array elements are found in a particular line of the file using pattern matching I need to remove 11 lines after that and the line itself from a file.

Problem: This change should be made in current file itself. So, I tried opening the file in read-write mode. But, I am seeing garbage being printed.

For example (see input tcl file above):

I need to remove all the lines (in this case 11) till "}" after "Power information for $rpow " (for example $rpow is vss) is found, with the line itself being removed where vss is an element of my remove_power_list array. This removal should happen for all the array elements.

Please if anybody can solve this issue?

Only problematic code being presented here:

#####Used help of StackOverflow member Praveen to come up with this code

my $rpow;

for $rpow (@remove_power_list) {

        my $bf_content;
        open $bf_content, '+<', $bf_bind;

           my $count = 0;

        while (<$bf_content>){

                  if($_ =~ /Power\s+information\s+for\s+$rpow\s+/) {
                $count = $. + 11; 
                }   

                else    
         {   
        if($count != 0 && $. < $count)
          {   

            }   
        elsif($count != 0 && $. == $count)
          {   
             $count =0; 
              }   
         else
          {   
             print $bf_content $_; 
              }   
         }

        }             
close $bf_content;
}

Note: I cannot install cpan File::Slurp.

Expected example output:

 # Bind
 ::d::autoBindmap $intfcName 

-------------so many other lines------------------------------

############ Power information for vdd #####################
#----------------------------
 #pg_vdd s100
#----------------------------
 #Add pg_vdd_dl interface
set  intfcName pg_vdd 1.0 s 100

 #Add Verilog port binding for vss
 ::d::autoBindmap $module pg_vdd $intfcName
{
 VDD vss_dl;
 }

-----------------------so many other lines-------------------------------
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
  • 2
    You have some obvious problems with your script. The biggest one I see is that you constantly re-open $outfile in your for loop, and in re-write mode, meaning at most you'll ever have the last line of output in your output file. But you haven't told us what specific problem(s) you're experiencing, so it's hard to address your question. – Jonathan Hall Nov 06 '14 at 03:24
  • @Flimzy, The problem is that I am not able to remove all the content of file using pattern matching and array looping technique I am using. Also, as you mentioned, when I try to remove fixed number of lines as per advice of Praveen I see all the last lines to be truncated. So, let me reword my question here:I need to remove lines from a input tcl file based on match with remove_power_list array element. And I need to remove 11 lines after "Power information for $p" is found. $p can be anything. And if remove_power_list has it then I need to remove 11 lines and that line too. – aa_electronics Nov 06 '14 at 19:29
  • @Flimzy: For example (see input tcl file above) : I need to remove all the lines (in this case 11 lines) till "}" after "Power information for $rpow " (for example $rpow is vss) is found, with the line itself to be removed. The "vss" is an element of my remove_power_list array. This removal should happen for all the array elements. So, I am left with no choice but open and close the file in read/write mode within "for loop" of array. And it is printing garbage in the file, while writing. I am using the code from user Pradeep, with some modification. – aa_electronics Nov 06 '14 at 21:25
  • @Flimzy : I have edited the original question. Hope it makes sense now. – aa_electronics Nov 06 '14 at 22:14
  • 1
    @aa_electronics Your question is still unclear. You keep saying "11 lines," but it seems like the blocks you're trying to delete could be variable length. The question would be clearer if you simply added a sample of the exact output you're trying to generate with your script. – ThisSuitIsBlackNot Nov 06 '14 at 23:10
  • Also, if you're trying to parse Verilog, you might take a look at [Verilog-Perl](https://metacpan.org/pod/Verilog-Perl). I don't know what you mean by "My perl packages does not support File:Slurp and other special Array packages," but I assume that means you think you can't install modules from CPAN. Perhaps that's a company policy that you can't avoid, but if not, you should know that [you don't need admin rights to install modules](http://stackoverflow.com/q/3735836). – ThisSuitIsBlackNot Nov 06 '14 at 23:21
  • @ThisSuitIsBlackNot : I am not parsing Verilog here. Tcl file is one of the input here. 11 lines after matching string, are fixed. And now, I have mentioned the expected output in question section. Also, I am looking into CPAN stuff you mentioned. But, meanwhile if I can get help without using CPAN File::Slurp module? – aa_electronics Nov 07 '14 at 00:00

1 Answers1

0

@aa_electronics: I believe there are lot of problems in your script . So as per your requirement i have written a perl code. Just have a look:

InputFile: (input.txt)

 # Bind
     ::d::autoBindmap $intfcName 


    ############ Power information for vss #####################
    #----------------------------
     #pg_vss s100
    #----------------------------
     #Add pg_vss_dl interface
    set  intfcName pg_vss 1.0 s 100

     #Add Verilog port binding for vss
     ::d::autoBindmap $module pg_vss $intfcName
    {
     VSSGND vss_dl;
     }

    ############ Power information for vdd #####################
    #----------------------------
     #pg_vdd s100
    #----------------------------
     #Add pg_vdd_dl interface
    set  intfcName pg_vdd 1.0 s 100

     #Add Verilog port binding for vss
     ::d::autoBindmap $module pg_vdd $intfcName
    {
     VDD vss_dl;
     }


     #write component 
     ::d::writeLib $module

Code:

use strict;
use warnings;   

my $infile = $ARGV[0];
my $outfile = "out.txt";

open my $fh,'<',$infile or die "Couldnt open the file $infile:$!" ; 
open my $out,'>',$outfile or die "Cannot write to the file $!"; 
my $count = 0;
my $var = 0;
my @final=();

my @remove_power_list = ("vcchg","vccl","vss");

   while(<$fh>)
        {
            #chomp;
            foreach my $rem(@remove_power_list) {
                $var++;
        my $line = 'Power\s+information\s+for\s+' . "$rem";
          if($_ =~ /$line/g)
           {
             $count = $. + 11;
            }
          else      
          {
             if($count != 0 && $. < $count)
              {
                 }
             elsif($count != 0 && $. == $count)
                {
                  $count =0;
                  }         
             else
              {
                if($var ==1)
                 {
                 push(@final,$_);
                  }
                }     
            }
        }  
      $var=0;  
    }

foreach my $rem(@remove_power_list)
 { 
 foreach my $res (@final)
   {
        my $line = 'Power\s+information\s+for\s+' . "$rem";
          if($res =~ /$line/g)
           {
           $res =~ s/$res//isg;
            }          
        }       
     } 

foreach my $finalval (@final)
 {
     print $out $finalval;
    }          
 close($fh);       
close($out);

Output: (out.txt)

# Bind
     ::d::autoBindmap $intfcName 


    ############ Power information for vss #####################

    ############ Power information for vdd #####################
    #----------------------------
     #pg_vdd s100
    #----------------------------
     #Add pg_vdd_dl interface
    set  intfcName pg_vdd 1.0 s 100

     #Add Verilog port binding for vss
     ::d::autoBindmap $module pg_vdd $intfcName
    {
     VDD vss_dl;
     }


     #write component 
     ::d::writeLib $module
Praveen
  • 902
  • 6
  • 21
  • thank you for answer. But, I forgot to mention that the remove_power_list array keeps on changing based on other part of the code I have in my huge script. So, can we use a for loop before while statement, to match those lines? Also, I need to remove the line "Power information for $p" ($p is vss) while removing those 11 lines. I din't mention that too. I think I can remove that if I don't put the print statement in "if" statement curly brackets. – aa_electronics Nov 06 '14 at 18:00
  • Sorry for the delay.I was busy with other things. Modified the code. Just have a look. – Praveen Nov 08 '14 at 18:36