Bug in Perl f77 namelist module 
Author Message
 Bug in Perl f77 namelist module

[Pardon me if some of you see this article multiple
times. I realized after my first post that I should
have also cross-posted to comp.lang.fortran. I have
already cancelled the previous posts.]

I created an extension module that may prove useful
to anyone using Fortran and the namelist extension
provided by, for example, the Sun f77 compiler. I
defined a Perl class called "Nmlfile", which lets you
read in namelist files using the Perl syntax:
my $nmlfile = new Nmlfile($filehandle);
$nmlfile->readnml;
$variable = $nmlfile->variable;
$nmlfile->printnml("nmlname" => "mynml");
etc.

I would like to distribute this via CPAN.
The problem is that when I read in character
strings, random junk sometimes gets appended
to them in my extension subroutine. Otherwise,
the module works great. Does anyone have any
interest in helping me to debug this problem?
Anyone out there have a use for Perl as glue
for legacy Fortran software?

Guy Berliner

--



Wed, 04 Aug 1999 03:00:00 GMT  
 Bug in Perl f77 namelist module

Quote:
> I created an extension module that may prove useful
> to anyone using Fortran and the namelist extension
> provided by, for example, the Sun f77 compiler. I
> defined a Perl class called "Nmlfile", which lets you
> read in namelist files using the Perl syntax:
> my $nmlfile = new Nmlfile($filehandle);
> $nmlfile->readnml;
> $variable = $nmlfile->variable;
> $nmlfile->printnml("nmlname" => "mynml");
> etc.

Sounds great.

Quote:
> I would like to distribute this via CPAN.
> The problem is that when I read in character
> strings, random junk sometimes gets appended
> to them in my extension subroutine. Otherwise,
> the module works great. Does anyone have any
> interest in helping me to debug this problem?

Since we don't use namelists I cannot help very
much.

Quote:
> Anyone out there have a use for Perl as glue
> for legacy Fortran software?

Yes, we are still using FORTRAN and have many routines
that parse FORTRAN files looking for particular items.
Does anyone know if there is someone working on perl
modules that parse or write FORTRAN.

Here are some of the things we do (not necessarily in perl):

  1. look for include files (that contain common
     block definitions) (perl)
  2. Search for variables which are set (c)
  3. Search for variables which are used (c)
  4. Write comments to top of file (shell)
  5. Write variable and common declarations to an include file
     using a data dictionary. (c)

Here are some ideas of things that would be nice.
  1. Write fortran line that conforms to the 72 column
     limit and adds the continuation indicator to
     column 6.
  2. Write FORTRAN comments.
  3. Generate a calling tree given a list of FORTRAN files

I know some of these can be done with other tools but it would
be nice to be able to do this with perl.

Any other ideas?

PS: I don't regularly read comp.lang.fortran so please cross post
    response.  Thanks.

--

\  Kipp E. Howard              | Voice: (206) 662-4932 Fax: (206) 662-4404   /


/  Seattle, WA  98124-2207     | WWW: http://www.iasl.ca.boeing.com/~keh3985 \



Fri, 06 Aug 1999 03:00:00 GMT  
 Bug in Perl f77 namelist module


Quote:
>   3. Generate a calling tree given a list of FORTRAN files

The following script that generates output suitable for printing.  A
call graph could easily be generated since all the information
necessary is stored in hashes.  It's not a full FORTRAN parser and far
from foolproof, but works for me.  The stuff that's left over after
&remove_literals should be suitable for analysis of COMMON variables,
but I've never tried.  If this script looks un-perlish to you: it was
originally written in Qawk.

+=========================================================================+
|ipolat.f                                                           polat1|
+------------------------------------+------------------------------------+
|calls                               |                           called by|
+------------------------------------+------------------------------------+
|feldbe      felden      housh1      |gummel      m_strodi    sepro       |
|prierr                              |sepro_s     vekplo      zanplo      |
+=========================================================================+
|ipolat.f                                                           housh1|
+------------------------------------------------------------+------------+
|calls                                                       |   called by|
+------------------------------------------------------------+------------+
|                                                            |polat1      |
+=========================================================================+
|ipolat.f                                                           polat3|
+------------------------------------------------+------------------------+
|calls                                           |               called by|
+------------------------------------------------+------------------------+
|feldbe      felden      housh3      prierr      |gummel      tlasep      |
+=========================================================================+
|ipolat.f                                                           housh3|
+------------------------------------------------------------+------------+
|calls                                                       |   called by|
+------------------------------------------------------------+------------+
|                                                            |polat3      |
+=========================================================================+

#!/usr/local/bin/perl
#
#
# slurp in whole paragraphs
#
$/ = "";
$* = 1;
#
$label = "^[0-9 ]{0,5}";
$lcont = "\n( {5}[^ ]|\t[0-9])";
$lcomm = "^[cd!*].*\n";
#
$header = 'format STDOUT =
'.'+==========================================================================+

'.' $file,                                                         $subroutine
'.'+--------------------------------------------------------------------------+
'.'|calls                                                            called by|
'.'+--------------------------------------------------------------------------+';
#
#

{
    open (FILE, $file) || warn "Can't open $file: $!\n";
    while (<FILE>)
    {
        tr/[A-Z]/[a-z]/;        # convert to lower-case
        s/$lcont//g;            # line-up continuation lines
        s/$label//g;            # remove labels
        s/$lcomm//g;            # remove commentary lines
        s/\n+/\n/g;             # remove empty lines
        s/[ \t]+//g;            # remove unnecessary whitespace
        split (/\n/, $_);       # split in statements
        &remove_literals;       # as I said, also removes remaining comments
        &process_keywords;
    }

Quote:
}

#

{


    {
        # lists all subroutines called by me


        {
            $is_called{$callee}++;
        }

        # lists all callers of myself


        {
            $gets_called{$caller}++;
        }

        # get that many columns for format and compute how many
        # columns are to be used for callee and caller
        $columns = 6;
        $chars   = (11+1);
        $ncallee = ($#callee > 0) ? $#callee : 0;
        $ncaller = ($#caller > 0) ? $#caller : 0;
        $lines = int(($ncallee + $ncaller) / $columns);
        do
        {
            $col1 = int($ncallee / ++$lines) + 1;
            $col2 = int($ncaller /   $lines) + 1;
        } while (($col1 + $col2) > $columns);
        if (($col1 +  $col2) < $columns)
        {
            $col1 = $columns-$col2;
        }

        # re-eval format
        $format = "format =\n+";
        for ($i = 0; $i < $columns; $i++)
        {
            $format .= "============";
        }

        for ($i = 2; $i < $columns; $i++)
        {
            $format .= "            ";
        }

        for ($i = 0; $i < $columns; $i++)
        {
            $format .= "------------";
        }
        $format .= "-+\n|calls       ";
        for ($i = 2; $i < $columns; $i++)
        {
            $format .= "            ";
        }
        $format .= "    called by|\n+";
        for ($i = 0; $i < $columns; $i++)
        {
            $format .= "------------";
        }
        $format .= "-+";
        substr ($format, -((2*$columns + $col2)*$chars + 10), 1) = "+";
        substr ($format, -(($columns + $col2)*$chars + 6), 1) = "|";
        substr ($format, -($col2*$chars + 2), 1) = "+";
        $format .= "\n|";
        for ($i = 0; $i < $columns; $i++)
        {

        }
        substr ($format, -($col2*$chars), 0) = "|";
        $format .= "|~~\n";
        for ($i = 0; $i < $col1; $i++)
        {

        }
        while ($i < $columns)
        {

            $i++;
        }
        chop $format;
        $format .= "\n.\n\n";
        eval ($format);

        for ($i = $ncallee+1; $i < $col1*$lines; $i++)
        {
            $callee[$i] = " "
        }
        for ($i = $ncaller+1; $i < $col2*$lines; $i++)
        {
            $caller[$i] = " "
        }
        write;

        undef %is_called;
        undef %gets_called;
        undef %callee;
        undef %caller;
    }

    print substr ($format, 9, $columns*$chars+4)

Quote:
}

#
sub process_keywords
{
    local($line);


    {

        if ($line =~ /(entry|subroutine|program)([\w\d]+)/)
        {
            $provides{$file} .= $2 . " ";
            $in_sub = $2;
            next;
        }
        if ($line =~ /(call)([\w\d]+)/)
        {
            $calls{$in_sub} .= $2 . " ";
            $called_by{$2} .= $in_sub . " ";
        }
    }

Quote:
}

#
sub remove_literals
{
    local($line, $pattern);
    local($first, $last, $length);


    {

        while ($line =~ /(['"])/)
        {
            $first  = index ($line, $1);
            $last   = index ($line, $1, $first + 1);
            $length = ($last > 0) ? $last - $first + 1 : 1;
            substr ($line, $first, $length) = "[]";
        }
        $line =~ s/!.*$//g;     # removes to-end-of-line-comments

    }

Quote:
}

#

Achim Gratz.

--+<[ It's the small pleasures that make life so miserable. ]>+--
WWW:    http://www.inf.tu-dresden.de/~ag7/{english/}

Phone:  +49 351 463 - 8325



Fri, 06 Aug 1999 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Bug in Perl f77 namelist module

2. fortran namelist reading perl module

3. fortran namelist reading perl module

4. ANNOUNCE: perl 5 package to parse Fortran NAMELIST data

5. Perl and FORTRAN namelists

6. Fortran namelist XS Adds junk to end of my C strings

7. NameList.pm anyone?

8. Fortran namelist XS Adds junk to end of my C strings

9. extracting value of variable from Fortran namelist

10. Reading FORTRAN namelist

11. Bug in XML::DOM perl module

12. Activestate Perl Bug #23103 Ptk dowhenidle/fileevent bug

 

 
Powered by phpBB® Forum Software