mirror of https://gitlab.com/QEF/q-e.git
162 lines
3.4 KiB
Perl
Executable File
162 lines
3.4 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
use strict;
|
|
|
|
{
|
|
my $maxdepth = 2; # default
|
|
|
|
if ($#ARGV > -1 && $ARGV[0] eq "-h") {
|
|
print STDERR "usage: $0 [-d maxdepth] [target subroutine(s)]\n";
|
|
print STDERR " builds the dependency tree of f90 files - run from the QE root directory\n";
|
|
print STDERR " defaults: maxdepth=2, targets=all f90 files under the current directory\n";
|
|
exit 0;
|
|
}
|
|
|
|
if ($#ARGV > -1 && $ARGV[0] eq "-d")
|
|
{
|
|
if ($#ARGV < 1)
|
|
{
|
|
print STDERR "error: maxdepth missing\n";
|
|
print STDERR "usage: $0 [-d maxdepth] [targets]\n";
|
|
exit 1;
|
|
}
|
|
$maxdepth = $ARGV[1];
|
|
if ($maxdepth !~ /^\d+$/)
|
|
{
|
|
print STDERR "error: non-numeric maxdepth\n";
|
|
print STDERR "usage: $0 [-d maxdepth] [targets]\n";
|
|
exit 1;
|
|
}
|
|
shift @ARGV;
|
|
shift @ARGV;
|
|
}
|
|
|
|
my $basedir = $0;
|
|
# Orig: the following is the directory where this script is
|
|
# $basedir =~ s/(.*)\/.*/$1/;
|
|
# the following works only if we run the script from QE root
|
|
$basedir = "./";
|
|
my @sources = split(/ /, `echo $basedir/*/*.f90 $basedir/*/*/*.f90`);
|
|
|
|
# grab program, function and subroutine declarations
|
|
my (%place, %fname, %pname);
|
|
foreach my $file (@sources)
|
|
{
|
|
open(IN, "$file");
|
|
while (<IN>)
|
|
{
|
|
$_ = "\L$_"; # cast everything to lowercase
|
|
if (/^[^!'""']*\bfunction\s+(\w+)/o && ! /^\s*end\s+function\b/o)
|
|
{
|
|
$fname{$1} = 1;
|
|
push_place(\%place, $1, $file);
|
|
}
|
|
elsif (/^\s*program\s+(\w+)/o)
|
|
{
|
|
$pname{$1} = 1;
|
|
push_place(\%place, $1, $file);
|
|
}
|
|
elsif (/^\s*(?:(?:pure|recursive)\s+)?subroutine\s+(\w+)/o)
|
|
{
|
|
push_place(\%place, $1, $file);
|
|
}
|
|
}
|
|
close(IN);
|
|
}
|
|
my @names = sort keys %place;
|
|
my @functions = sort keys %fname;
|
|
|
|
# if no arguments are specified, stat all programs
|
|
my @targets = @ARGV;
|
|
if ($#targets < 0)
|
|
{
|
|
@targets = sort keys %pname;
|
|
}
|
|
|
|
my %cache;
|
|
foreach my $name (@targets)
|
|
{
|
|
stat_name($name, \%place, \@functions, \%cache, 0, "", $maxdepth);
|
|
}
|
|
}
|
|
|
|
sub push_place
|
|
{
|
|
my ($place, $name, $file) = @_;
|
|
if (defined $$place{$name})
|
|
{
|
|
$$place{$name} = "$$place{$name} $file";
|
|
}
|
|
else
|
|
{
|
|
$$place{$name} = "$file";
|
|
}
|
|
}
|
|
|
|
sub stat_name
|
|
{
|
|
my ($name, $place, $functions, $cache, $depth, $indent, $maxdepth) = @_;
|
|
print "$indent$name\n";
|
|
|
|
if ($depth >= $maxdepth || ! defined $$place{$name})
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (! defined $$cache{$name})
|
|
{
|
|
my %cname;
|
|
my @files = split(/ /, $$place{$name});
|
|
foreach my $file (@files)
|
|
{
|
|
my $current = "";
|
|
open(IN, $file);
|
|
while (<IN>)
|
|
{
|
|
$_ = "\L$_";
|
|
if (/^\s*program\s+(\w+)/o)
|
|
{
|
|
$current = "$1";
|
|
}
|
|
elsif (/^\s*(?:(?:pure|recursive)\s+)?subroutine\s+(\w+)/o)
|
|
{
|
|
$current = "$1";
|
|
}
|
|
elsif (/^[^!'""']*\bfunction\s+(\w+)/o)
|
|
{
|
|
$current = "$1";
|
|
}
|
|
# here we are inside the relevant program/subroutine/function
|
|
elsif ($current eq $name)
|
|
{
|
|
# subroutine calls
|
|
if (/^\s*call\s+(\w+)/o)
|
|
{
|
|
$cname{$1} = 1;
|
|
}
|
|
# function calls
|
|
foreach my $fun (@$functions)
|
|
{
|
|
if (/^[^!'""']*\b$fun\b/)
|
|
{
|
|
$cname{$fun} = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
close(IN);
|
|
}
|
|
my @calls = sort keys %cname;
|
|
$$cache{$name} = \@calls;
|
|
}
|
|
|
|
foreach my $call (@{$$cache{$name}})
|
|
{
|
|
if ($call ne $name)
|
|
{
|
|
stat_name($call, $place, $functions, $cache,
|
|
$depth+1, " $indent", $maxdepth);
|
|
}
|
|
}
|
|
}
|