Unable to print after while loop in perl

124 views Asked by At
BEGIN {
   use FindBin;
   $scriptsDir = $FindBin::RealBin;
}

 sub print_log {
  ($log, $msg) = ($_[0], $_[1]);
  print $log $msg;
     }


$opt_rh_gsr = "path_to_file";
open(FO, "$opt_rh_gsr") || die "-F-: Can not open file \n";
while(<FO>) {
  if(/vdd_nets/) {
          $vdd_net = 1;
          $vdd_string = "VDD_NETS \{ \n";
               }
  if(/gnd_nets/) {
          $gnd_net = 1;
 }
     if(($gnd_net == 1)) {
     chomp();
     $new_line = $_;
     @split_new_line = split(":", $new_line);
     }
   if(($gnd_net == 1) && /\}/) {
      $gnd_net = 0;
      $gnd_string .= "\} \n";
      exit;
       }
  if($vdd_net) {
    if(/^\s*\S+\s+\S+\s+{/) {
      $paren++;
    }
    if (0 != $paren && /^\s*(\w+)\s*$/) {
     $vdd_nets{$1} = $parenvolt;
      next;
    }
    if(/^\s*}\s*$/ || /^\s+$/) {
      if (0 == $paren) {
        $vdd_net = 0; next;
      }
      else {
        $paren--;  next;
      }
    }
    chomp();
    if(/\s*\}\s*$/ && ($vdd_net == 1)){
    s/\'//g;
    $vdd_net = 0;
    @_ = split(":");
    $vdd_string .= "$_[0]  $_[1] \n";
    $vdd_string .=  "\} \n";
    next;
    }
      
  if($gnd_net) {
    if(/^\s*\}\s+$/ || /^\s+$/) {
      $gnd_net = 0;
      next;
    }
    #chomp();
    if(/\s*\}\s*$/ && ($gnd_net == 1)){
    s/\'//g;
    $gnd_net = 0;
    }
    @_ = split();
    $GNDNET = $_[0];
    if ($_[0] =~ /^\w+$/) {
      $groundnets{$_[0]} = 1;
     
    }
  }
}
}
print " done reading \n";
close(FO); 

print "closed file \n";

The above is not printing the last 2 print statement (before and after the close of file handle). I tried print STDOUT, that didn't work. I also tried to flush, that didn't work either.

The script is exiting after executing, so it is not stuck in a infinite loop anywhere. I tries using perl5.6 and 5.8, but both of them have the same problem.

1

There are 1 answers

2
Dada On

To exit a loop, you should use the keyword last instead of exit (which exits the whole program). This if:

if(($gnd_net == 1) && /\}/) {
    $gnd_net = 0;
    $gnd_string .= "\} \n";
    print "exiting loop $gnd_string \n";
    exit;
}

Should thus be:

if(($gnd_net == 1) && /\}/) {
    $gnd_net = 0;
    $gnd_string .= "\} \n";
    print "exiting loop $gnd_string \n";
    last;
}

(unless you actually wanted to exit the program, in which case the print should rather have been print "exiting program...")


A few tips:

  • Always add use strict and use warnings at the beginning of your scripts. It will catch many mistakes and save you a lot of time.

  • Use 3-operand open to open files (ie, open FILEHANDLE,MODE,EXPR instead of open FILEHANDLE,EXPR), and lexical filehandles (ie, $FO instead of FO). Your open should thus have been: open my $FO, '<', $opt_rh_gsr instead of open(FO, "$opt_rh_gsr").

  • Adding || die "-F-: Can not open file \n" after open is a good idea, but 1) you should do or die instead of || die (in this specific case it doesn't matter, but with or rather than ||, you can omit the parenthesis around open's arguments), and 2) you should add the name of the file you were trying to open (in that case, you'd print die "-F-: Can not open file '$opt_rh_gsr'). 3) add $! to the die to have the error message (die "-F-: Can not open file '$opt_rh_gsr': $!). And 4), as suggested by TLP, don't add a newline at the end of a die string.

  • sub print_log { ($log, $msg) = ($_[0], $_[1]); ... could have been sub print_log { ($log, $msg) = @_;; it's a bit more idiomatic and concise.

  • Indent properly your code. It's possible that indentation was lost in the copy-paste, but, if it's not the case, then you should indent better your code. This will save you a lot of time when writing/reading your code, and will save other people even more time when they'll read your code. Most IDEs have indentation features that can help you indent the code.