Regular expression segmentation Fault with in-place substitution

Discussion in 'Perl Misc' started by Riad KACED, Jul 29, 2009.

  1. Riad KACED

    Riad KACED Guest

    Dear Perl Fellows,

    I'm trying to Find and Replace a pattern with in-place edit.
    I have opened the file using the Tie::File module as advised in
    perlfaq5.
    My regular expression is quite simple :
    s/\b$find\b/$replace/g, i.e global substitution of word anchored
    pattern.
    I found that the above fails whenever the pattern shows up more than
    once in a line.
    The Segmentation fault goes off by removing either the global modifier
    or the word anchors. This is not what I want though. I spent entire
    morning trying to figure it out but I have failed I'm afraid :-(

    Anyway, my script is:

    #!/usr/local/bin/perl -w

    use strict;
    use Tie::File;
    use File::Copy;

    my $spectreModelFile=shift;
    my $spectreSubcktName=shift;
    my @newpinNames=@ARGV;

    my @spectreSubcktpinNames = getSpectreSubcktTerminals
    ($spectreModelFile,$spectreSubcktName);

    my $newpinNamesLngth = @newpinNames;
    my $spectreSubcktpinNamesLngth = @spectreSubcktpinNames;

    unless ($newpinNamesLngth == $spectreSubcktpinNamesLngth)
    {
    die "Port Number mismatch: Given=$newpinNamesLngth, Needed=
    $spectreSubcktpinNamesLngth\n" ;
    }

    copy($spectreModelFile,"$spectreModelFile.bak");
    for (my $i=0; $i<$newpinNamesLngth ; $i++)
    {
    my $find=$spectreSubcktpinNames[$i];
    my $replace=$newpinNames[$i];
    print("Step # $i : find=$find, replace=$replace\n");
    unless($find eq $replace)
    {
    findAndReplace($spectreModelFile,$find,$replace);
    }
    }



    #-----------------------------------------------------------
    # subroutine : findAndReplace
    #-----------------------------------------------------------
    sub findAndReplace
    {
    my ($inputFile,$find,$replace)=@_;
    print("Attempting to replace $find by $replace ... ");
    tie my @inputFile,'Tie::File',$inputFile or die "$inputFile : $!\n";
    for (@inputFile)
    {
    s/\b$find\b/$replace/g; # This comes with a Segmentation fault
    #s/\b$find\b/$replace/; # This is fine but it is not why I want
    #s/$find/$replace/g; # This is fine but it is not why I want
    }
    untie @inputFile;
    print("OK\n");
    }
    #-----------------------------------------------------------
    # subroutine : getSpectreSubcktTerminals
    #-----------------------------------------------------------
    sub getSpectreSubcktTerminals
    {
    my ($spectreModelFile,$spectreSubcktName)=@_;
    open(SPECTREMODELFILE,"< $spectreModelFile") or die "cannot read-
    open $spectreModelFile : $!";
    my @subcktTerminals;

    while (my $line=<SPECTREMODELFILE>)
    {
    # Skip the commented lines. Blank lines : m/^\s*$/ are left
    next if ($line =~ m/^\s*$/); # Skip blank lines
    next if ($line =~ m/^s*\*/); # Skip commented lines, starting
    with a leading Opt WS + '*'
    next if ($line =~ m/^s*\/\//);# Skip commented lines, starting
    with a leading Opt WS + '//'
    # subckt and2 A B Vdd Vss Y
    if ($line =~ m/^\s*subckt\s+\b$spectreSubcktName\b((?:\s+\w+)+)/)
    {
    my $subcktTerminals=$1;
    $subcktTerminals =~ s/^\s+//;
    @subcktTerminals=split(/\s+/,$subcktTerminals);
    last;
    }
    }
    close(SPECTREMODELFILE);
    @subcktTerminals;
    }

    # EOF script

    The script could be run as following :

    myScript.pl myInFile mySubckt p1 p2 p3 p4 p5

    myInFile is a text file (a Spectre subcircuit to be more precise):
    // File starts here
    subckt mySubckt a1 a12 vdd vss out
    m0 vdd a1 2 vss myNmos l=1u w=10u
    m1 vss a12 out vss myPmos l=1u w=10u
    m2 2 a12 out out myPmos l=1u w=10u
    ends mySubckt
    // file ends here

    FYI:
    Perl Version: v5.8.0 (5.008)
    OS = Suse Linux ES 9, Patch 3, kernel release 2.6.5-7.287.3.PTF.
    363939.1-smp

    Thanks in advance for your help !

    regards,
    Riad.
     
    Riad KACED, Jul 29, 2009
    #1
    1. Advertising

  2. Riad KACED

    Sylvain Guest

    On Jul 29, 1:52 pm, Riad KACED <> wrote:
    > Dear Perl Fellows,
    >
    > I'm trying to Find and Replace a pattern with in-place edit.
    > I have opened the file using the Tie::File module as advised in
    > perlfaq5.
    > My regular expression is quite simple :
    > s/\b$find\b/$replace/g, i.e global substitution of word anchored
    > pattern.
    > I found that the above fails whenever the pattern shows up more than
    > once in a line.
    > The Segmentation fault goes off by removing either the global modifier
    > or the word anchors. This is not what I want though. I spent entire
    > morning trying to figure it out but I have failed I'm afraid :-(
    >
    > Anyway, my script is:
    >
    > #!/usr/local/bin/perl -w
    >
    > use strict;
    > use Tie::File;
    > use File::Copy;
    >
    > my $spectreModelFile=shift;
    > my $spectreSubcktName=shift;
    > my @newpinNames=@ARGV;
    >
    > my @spectreSubcktpinNames = getSpectreSubcktTerminals
    > ($spectreModelFile,$spectreSubcktName);
    >
    > my $newpinNamesLngth = @newpinNames;
    > my $spectreSubcktpinNamesLngth = @spectreSubcktpinNames;
    >
    > unless ($newpinNamesLngth == $spectreSubcktpinNamesLngth)
    > {
    >   die "Port Number mismatch: Given=$newpinNamesLngth, Needed=
    > $spectreSubcktpinNamesLngth\n" ;
    >
    > }
    >
    > copy($spectreModelFile,"$spectreModelFile.bak");
    > for (my $i=0; $i<$newpinNamesLngth ; $i++)
    > {
    >   my $find=$spectreSubcktpinNames[$i];
    >   my $replace=$newpinNames[$i];
    >   print("Step # $i : find=$find, replace=$replace\n");
    >   unless($find eq $replace)
    >   {
    >     findAndReplace($spectreModelFile,$find,$replace);
    >   }
    >
    > }
    >
    > #-----------------------------------------------------------
    > # subroutine : findAndReplace
    > #-----------------------------------------------------------
    > sub findAndReplace
    > {
    >   my ($inputFile,$find,$replace)=@_;
    >   print("Attempting to replace $find by $replace ... ");
    >   tie my @inputFile,'Tie::File',$inputFile or die "$inputFile : $!\n";
    >   for (@inputFile)
    >   {
    >     s/\b$find\b/$replace/g; # This comes with a Segmentation fault
    >     #s/\b$find\b/$replace/;  # This is fine but it is not why I want
    >     #s/$find/$replace/g; # This is fine but it is not why I want
    >   }
    >   untie @inputFile;
    >   print("OK\n");}
    >
    > #-----------------------------------------------------------
    > # subroutine : getSpectreSubcktTerminals
    > #-----------------------------------------------------------
    > sub getSpectreSubcktTerminals
    > {
    >   my ($spectreModelFile,$spectreSubcktName)=@_;
    >   open(SPECTREMODELFILE,"< $spectreModelFile") or die "cannot read-
    > open $spectreModelFile : $!";
    >   my @subcktTerminals;
    >
    >   while (my $line=<SPECTREMODELFILE>)
    >   {
    >     # Skip the commented lines. Blank lines : m/^\s*$/ are left
    >     next if ($line =~ m/^\s*$/);  # Skip blank lines
    >     next if ($line =~ m/^s*\*/);  # Skip commented lines, starting
    > with a leading Opt WS + '*'
    >     next if ($line =~ m/^s*\/\//);# Skip commented lines, starting
    > with a leading Opt WS + '//'
    >     # subckt and2 A B Vdd Vss Y
    >     if ($line =~ m/^\s*subckt\s+\b$spectreSubcktName\b((?:\s+\w+)+)/)
    >     {
    >       my $subcktTerminals=$1;
    >       $subcktTerminals =~ s/^\s+//;
    >       @subcktTerminals=split(/\s+/,$subcktTerminals);
    >       last;
    >     }
    >   }
    >   close(SPECTREMODELFILE);
    >   @subcktTerminals;
    >
    > }
    >
    > # EOF script
    >
    > The script could be run as following :
    >
    >  myScript.pl myInFile mySubckt p1 p2 p3 p4 p5
    >
    > myInFile is a text file (a Spectre subcircuit to be more precise):
    > // File starts here
    > subckt mySubckt a1 a12 vdd vss out
    > m0 vdd a1 2 vss myNmos l=1u w=10u
    > m1 vss a12 out vss myPmos l=1u w=10u
    > m2 2 a12 out out myPmos l=1u w=10u
    > ends mySubckt
    > // file ends here
    >
    > FYI:
    > Perl Version: v5.8.0 (5.008)
    > OS = Suse Linux ES 9, Patch 3, kernel release 2.6.5-7.287.3.PTF.
    > 363939.1-smp
    >
    > Thanks in advance for your help !
    >
    > regards,
    > Riad.


    Hello my Friend Riad,

    You're using the \b to find the word begin/end.
    Have you tried this expression by changing "\b" to "\s+" ?
    Does chrash also ?


    Regards,

    Sylvain
     
    Sylvain, Jul 29, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VSK
    Replies:
    2
    Views:
    2,354
  2. Vibha Tripathi

    Regular Expression for pattern substitution

    Vibha Tripathi, Jul 1, 2005, in forum: Python
    Replies:
    3
    Views:
    323
    Devan L
    Jul 1, 2005
  3. naugiedoggie
    Replies:
    5
    Views:
    349
    naugiedoggie
    Aug 30, 2010
  4. Iñaki Baz Castillo

    Help with an "easy" regular expression substitution

    Iñaki Baz Castillo, Dec 14, 2008, in forum: Ruby
    Replies:
    13
    Views:
    188
    Mark Thomas
    Dec 16, 2008
  5. Replies:
    2
    Views:
    73
    Peter Scott
    May 9, 2006
Loading...

Share This Page