File Coverage

blib/lib/CallGraph/Lang/Fortran.pm
Criterion Covered Total %
statement 38 38 100.0
branch 14 16 87.5
condition n/a
subroutine 4 4 100.0
pod 1 1 100.0
total 57 59 96.6


line stmt bran cond sub pod time code
1             package CallGraph::Lang::Fortran;
2              
3             $VERSION = '0.55';
4              
5 1     1   24613 use strict;
  1         2  
  1         38  
6 1     1   5 use warnings;
  1         2  
  1         29  
7              
8 1     1   6 use base 'CallGraph';
  1         6  
  1         546  
9              
10             =head1 NAME
11              
12             CallGraph::Lang::Fortran - Fortran 77 parser for creating call graphs
13              
14             =head1 SYNOPSIS
15              
16             use CallGraph::Lang::Fortran;
17             my $graph = CallGraph::Lang::Fortran->new(files => [glob('*.f')]);
18             print $graph->dump;
19              
20             =head1 DESCRIPTION
21              
22             This module is a subclass of L which implements parsing Fortran 77
23             code for building the call graph.
24              
25             =head1 METHODS
26              
27             This module inherits all the methods from L. It defines only one
28             additional method:
29              
30             =over
31              
32             =item $graph->parse($fh)
33              
34             Parse the program using the given filehandle $fh. Note that you don't really
35             have to call this method directly, because it's called automatically whenever
36             you specify a file via the add_files or add_lines method, or via the
37             files or lines options to the constructor.
38              
39             This is the one function you have to override if you want to implement your
40             own subclass of L for parsing another language.
41              
42             =cut
43              
44             sub parse {
45 2     2 1 4 my ($self, $fh) = @_;
46              
47 2         118 my @lines = map uc, <$fh>; # slurp file and normalize case
48 2         29 s/\t/ / for (@lines); # get rid of tabs
49              
50             # build function list
51 2         7 my @func_list = ("dummy");
52 2         4 for (@lines) {
53 57 100       106 if(/^ .*?FUNCTION\s*(\w+)/) {
54 1         4 push @func_list, $1;
55             }
56             }
57 2         7 my $re_func = join(' *\(|', @func_list);
58 2         82 $re_func = qr/($re_func *\()/;
59              
60             # build call table
61 2         5 my ($sub);
62 2         10 my $state = 0;
63 2         6 for (@lines) {
64 57 50       122 next if /^[C*]/;
65 57 100       135 if ($state == 0) { # not in a block
    50          
66 27 100       103 if(/^ *(SUBROUTINE|.*FUNCTION|PROGRAM)\s*(\w+)/) {
67 13         90 my ($type, $name) = ($1, $2);
68 13         40 $sub = $self->new_sub(name => $name, type => 'internal');
69 13 100       31 if ($type eq 'PROGRAM') {
70 2         9 $self->root($sub);
71             }
72 13         22 $state = 1, next;
73             }
74             } elsif ($state == 1) { # inside a block
75 30 100       78 if (/^\s+END\s*$/) { # end of block
76 13         15 $state = 0;
77 13         38 next;
78             }
79 17 100       148 if (/CALL (\w+)/i) { # subroutine call
80 15         39 $self->add_call($sub->name, $1);
81             }
82 17         106 while (/$re_func/g) { # look for function calls
83 1         2 my $func = $1;
84 1         10 $func =~ s/ *\($//;
85 1         3 $self->add_call($sub->name, $func);
86             }
87             }
88             }
89             }
90              
91              
92             1;
93              
94             =back
95              
96             =head1 BUGS
97              
98             The parser is simplistic, so it might not handle every edge case (such as funny
99             use of whitespace and continuation lines) properly.
100              
101             =head1 VERSION
102              
103             0.55
104              
105             =head1 SEE ALSO
106              
107             L, L, L
108              
109             =head1 AUTHOR
110              
111             Ivan Tubert Eitub@cpan.orgE
112              
113             =head1 COPYRIGHT
114              
115             Copyright (c) 2004 Ivan Tubert. All rights reserved. This program is free
116             software; you can redistribute it and/or modify it under the same terms as
117             Perl itself.
118              
119             =cut
120              
121              
122