Any advice on how to fix this?

B

Bruce Bowler

I'll start by saying I'm NOT a perl programmer and I'm not sure this is
the right group, but I'm sure you'll tell me where to go if it's not :)

I have a perl script that I didn't write that works with perl 5.005_03
(solaris 2.7). It doesn't even compile with 5.8.0 (Redhat 8.0).

The error message from the compiler is

Can't modify reference constructor in list assignment at ./f77toM.pl line 465, near ");"
Execution of ./f77toM.pl aborted due to compilation errors.

The code in question is

for ( $ifmt=0;$ifmt<=$#fmt_array;$ifmt++ ) {

($space_str,$nchars,$imat,\@fmt_matlab,\@fmt_matvar) =
parse_write_fmt($space_str,$nchars,$ifmt,$imat,\@fmt_array,\@fmt_matlab,\@fmt_matvar,\@fmtstr,\@var_type);

} # end for on ifmt

where line 465 is the "parse_write_fmt" line.

The entire script is almost 3K lines long so I wont post it, but if you
want to examine the whole thing, it can be found at
ftp://ftp.math.umn.edu/pub/MCIM/f77toM.pl.gz

TIA,
Bruce

--
+-------------------+---------------------------------------------------+
Bruce Bowler | The most dangerous thing in the world is to leap a
1.207.633.9600 | chasm in two jumps. - David Lloyd George
(e-mail address removed) |
+-------------------+---------------------------------------------------+
 
J

John W. Krahn

Bruce said:
I'll start by saying I'm NOT a perl programmer and I'm not sure this is
the right group, but I'm sure you'll tell me where to go if it's not :)

I have a perl script that I didn't write that works with perl 5.005_03
(solaris 2.7). It doesn't even compile with 5.8.0 (Redhat 8.0).

The error message from the compiler is

Can't modify reference constructor in list assignment at ./f77toM.pl line 465, near ");"
Execution of ./f77toM.pl aborted due to compilation errors.

That warning must have been added to version 5.8 as it doesn't produce a
warning in version 5.6.

The code in question is

for ( $ifmt=0;$ifmt<=$#fmt_array;$ifmt++ ) {

($space_str,$nchars,$imat,\@fmt_matlab,\@fmt_matvar) =

Should be written as:

( $space_str, $nchars,$imat ) =

Or probably:

( $space_str, $nchars,$imat, $fmt_matlab_ref, $fmt_matvar_ref ) =

parse_write_fmt($space_str,$nchars,$ifmt,$imat,\@fmt_array,\@fmt_matlab,\@fmt_matvar,\@fmtstr,\@var_type);

} # end for on ifmt

where line 465 is the "parse_write_fmt" line.

The entire script is almost 3K lines long so I wont post it, but if you
want to examine the whole thing, it can be found at
ftp://ftp.math.umn.edu/pub/MCIM/f77toM.pl.gz

If you and the original author don't mind a little constructive
criticism. :)

49 # Typical usage stuff here.
50 if ( 0 > $#ARGV ) { # Should be one arg, at least.
51 usage();
52 } # endif

The usual perl idiom is:

unless ( @ARGV ) {
usage();
}

58 for ( $ifl=0;$ifl<=$#ARGV;$ifl++ ) { # Loop over arg list
files.
59
60 $fname = $ARGV[ $ifl ];

The usual perl idiom is:

for my $fname ( @ARGV ) {

71 # Copy Fortran file to backup, open file with original name
for input.
72 $file_bkp = "";$file_bkp .= $fname."\.bkp";

my $file_bkp = "$fname.bkp";

73 system("cp -f $fname $file_bkp");

Using system with a string will run the process via the shell which
means that if there are any shell meta-characters in $fname or $file_bkp
it may not work as expected. You should also verify that system()
executed the command correctly.

89 # Read file in, scanning for labels, managing continuations,
etc.
90 # This is an initial parsing.
91 open( F77FL, "<$file_bkp" );

You should _ALWAYS_ verify that the file opened correctly.

93 $lineno = 0;
94 foreach ( <F77FL> ) {

Using foreach on a filehandle will slurp the entire file into a list in
memory. You should use a while loop instead and if you use a while loop
the current line number will be in the $. variable so $lineno is not
needed.

246 # Now that we have the text, let's parse.
247 open( MFL, ">$m_file" );

You should _ALWAYS_ verify that the file opened correctly.

436 $fmt_edited =~ s/N([^\,|^\)])/N\,$1/g;
437 $fmt_edited =~ s/N([^\,|^\)])/N\,$1/g;

The regular expression reads 'N' followed by a character that is not ','
or '|' or '^' or ')'.

438 $fmt_edited =~ s/([^\,|^\(])N/$1\,N/g;
439 $fmt_edited =~ s/([^\,|^\(])N/$1\,N/g;

The regular expression reads a character that is not ',' or '|' or '^'
or '('.followed by a 'N'.
If you really want to match '|' or '^' then it is fine but it looks like
you really want:

$fmt_edited =~ s/N([^,\)])/N,$1/g;
$fmt_edited =~ s/N([^,\)])/N,$1/g;
$fmt_edited =~ s/([^,\(])N/$1,N/g;
$fmt_edited =~ s/([^,\(])N/$1,N/g;

A lot of the character classes in the code use '|' erroneously.

There are probably some more corrections that could be made but that is
all I can handle for now. :) Oh, by the way, you should have strict
enabled and declare all your variables with my().

HTH

John
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top