trick/bin/pm/mis_dep.pm
Alex Lin 14a75508a3 Cleaning up once include variables and copyright cleanup.
Changed all header file once include variables to follow the same naming
convention and not start with any underscores.  Also deleted old
incorrect copyright notices.  Also removed $Id: tags from all files.

Fixes #14.  Fixes #22.
2015-03-23 16:03:14 -05:00

286 lines
8.5 KiB
Perl

package mis_dep ;
use Exporter ();
@ISA = qw(Exporter);
@EXPORT = qw(mis_dep mis_catalog_dep traverse_tree);
use Cwd ;
use File::Basename ;
use strict ;
use Cwd 'abs_path';
use trick_print ;
use gte ;
my @mis_inc_paths ;
my %processed_files ;
my %mis_depends_tree ;
# Get TRICK_CFLAGS and parse out -I include paths
sub mis_dep ($@) {
my $file ;
my %all_depend_trees ;
my ($k , $a) ;
my ($sim_ref , @fileList) = @_;
@mis_inc_paths = $ENV{"TRICK_CFLAGS"} =~ /-I\s*(\S+)/g ;
push @mis_inc_paths , "../include" ;
@mis_inc_paths = grep !/trick_source/, @mis_inc_paths ;
push @mis_inc_paths , "$ENV{TRICK_HOME}/trick_source" ;
my @valid_inc_paths ;
foreach (@mis_inc_paths) {
push @valid_inc_paths , $_ if ( -e $_ ) ;
}
@mis_inc_paths = @valid_inc_paths ;
@fileList = grep !/\.h$|\.H$|\.hh$|\.h\+\+$/ , @fileList ;
foreach $file ( @fileList ) {
if ( $file ne "" ) {
undef %mis_depends_tree ;
$file = abs_path(dirname($file)) . "/" . basename($file) ;
trick_print($$sim_ref{fh}, "Getting dependencies for $file\n" , "normal_cyan" , $$sim_ref{args}{v}) ;
get_depends($file, $sim_ref);
%{$all_depend_trees{$file}} = %mis_depends_tree ;
$all_depend_trees{$file}{last_look} = time ;
}
}
return \%all_depend_trees ;
}
sub traverse_tree {
my ($file, $level, %curr_tree) = @_ ;
my $a ;
print " " x $level , $file , "\n";
foreach $a ( @{$curr_tree{$file}} ) {
if ( $a ne $file ) {
traverse_tree($a, $level+1, %curr_tree) ;
}
}
}
# Show Depends Recursive Algorithm
sub get_depends($$) {
my $file ;
my $sim_ref ;
my @list_objects ;
my @list_libs ;
my $found_dep ;
my @lib_list ;
my $contents ;
my $size ;
my $libdep ;
my $language ;
my ( $full_path ) ;
my ($rcs_file_name, $rcs_ver, $rcs_date, $rcs_owner ) ;
($file, $sim_ref) = @_;
# If you have already seen this dependency, then don't process
# Trim the tree ! And prevent infinite circular recursion !!! Yikes ...
return if ( exists $processed_files{$file} ) ;
# Add this file to processed list, if it is a full path
$processed_files{$file} = 1 ;
open FILE, $file or die "Could not process $file\n";
seek FILE , 0 , 2 ;
$size = tell FILE ;
seek FILE , 0 , 0 ;
read FILE , $contents , $size;
close(FILE);
while ( $contents =~ /LIBRARY(\s|_)DEPENDENC(Y|IES):[^(]*(.*?)\)([A-Z \t\n\r]+:|[ \t\n\r]*\*)/gsi ) {
$libdep .= $3 ;
}
if ( $libdep =~ /#/ ) {
(my $cc = gte("TRICK_CC")) =~ s/\n// ;
my @defines = $ENV{"TRICK_CFLAGS"} =~ /(-D\S+)/g ;
my $temp ;
open FILE, "echo \"$libdep\" | cpp -P @defines |" ;
while ( <FILE> ) {
$temp .= $_ ;
}
$libdep = $temp ;
}
@lib_list = split /\)[ \t\n\r\*]*\(/ , $libdep ;
foreach (@lib_list) {
s/\(|\)|\s+//g ;
s/\${(.+?)}/$ENV{$1}/eg ;
}
@list_objects = grep /\.o$/ , @lib_list ;
@list_libs = grep /\.so$|\.a$/ , @lib_list ;
# Always add self-dependency
push @{$mis_depends_tree{$file}} , $file ;
# Now for each object, construct full path to object's src and find src file
foreach my $o (@list_objects) {
# look for object code with source
$found_dep = find_depends_file($file,$o,$sim_ref) ;
# Did not find dependency
if ( $found_dep == 0 ) {
$o =~ s/\.[\w\+]+$/\.o/ ;
trick_print($$sim_ref{fh}, "ERROR: Dependency \"$o\" not found for \"$file\"\n", "title_red" , $$sim_ref{args}{v}) ;
exit( -1 ) ;
}
}
# Now for each lib, construct full path to lib's src and add to list
foreach my $l ( @list_libs ) {
my ($rel_path , $lib_name ) ;
($rel_path , $lib_name ) = $l =~ /(?:(.*)\/)?([^\/]+)/ ;
if ($rel_path eq "") {
$found_dep = 1 ;
$lib_name =~ s,lib,,;
$lib_name =~ s,\.so$|\.a$,,;
$processed_files{"-l$lib_name"} = 1 ;
push @{$mis_depends_tree{$file}} , "-l$lib_name" ;
trick_print($$sim_ref{fh}, " $lib_name\n" , "debug_white" , $$sim_ref{args}{v}) ;
} else {
$found_dep = 0 ;
foreach my $ipath ( @mis_inc_paths ) {
# Construct possible full paths to lib dir from include paths
$full_path = $ipath . "/" . $rel_path;
if ( -s $full_path ) {
$found_dep = 1;
$lib_name = $full_path ."/object_\${TRICK_HOST_CPU}/". $lib_name ;
# remove ../
while ( $lib_name =~ s,/[^/]+/\.\.,, ) {}
push @{$mis_depends_tree{$file}} , $lib_name ;
trick_print($$sim_ref{fh}, " $lib_name\n" , "debug_white" , $$sim_ref{args}{v}) ;
$processed_files{$lib_name} = 1 ;
last;
}
}
}
# Did not find dependency
if ( $found_dep == 0 ) {
trick_print($$sim_ref{fh}, "ERROR: Dependency $l not found for $file\n", "title_red" , $$sim_ref{args}{v}) ;
exit( -1 ) ;
}
}
}
sub find_depends_file($$$) {
my ($file, $o , $sim_ref) ;
my @list_languages ;
my $lex_yacc ;
my ( $full_path , $full_path1 , $full_path2 ) ;
my ( $curr_path ) ;
my ( $dep_to_search ) ;
($file , $dep_to_search, $sim_ref) = @_;
$o = $dep_to_search ;
$curr_path = dirname($file) ;
# Decide how to search through languages
opendir THISDIR, $curr_path or die "Could not open the directory of $curr_path" ;
$lex_yacc = grep /\.[ly]$/ , readdir THISDIR ;
if ( $lex_yacc ) {
@list_languages = ("y", "l", "c", "cpp" , "cc" , "cxx" , "C" , "c\+\+");
}
else {
@list_languages = ("c", "cpp" , "cc" , "cxx" , "C" , "c\+\+", "y", "l");
}
# Otherwise use TRICK_CFLAGS and find it
if ( $dep_to_search !~ /\.o$/ ) {
foreach my $ipath ( $curr_path , @mis_inc_paths ) {
if ( -s "$ipath/$dep_to_search" ) {
my $f = "$ipath/$dep_to_search" ;
$full_path = abs_path(dirname($f)) . "/" . basename($f) ;
push @{$mis_depends_tree{$file}} , $full_path ;
trick_print($$sim_ref{fh}, " $full_path\n" , "debug_white" , $$sim_ref{args}{v}) ;
get_depends($full_path , $sim_ref);
return(1) ;
}
}
} else {
foreach my $ipath ( $curr_path , @mis_inc_paths ) {
foreach my $lang ( @list_languages ) {
my $found_dep ;
my ($file_name ) ;
my ($dir_name ) ;
my ($rspath , $rpath ) ;
$o =~ s/\.[\w\+]+$/\.$lang/ ;
#
# Construct possible full paths to src from include paths
#
$file_name = basename($o) ;
$dir_name = dirname($o) ;
# if full path sepcified (possible, but not recommended)
# don't prepend include path.
if ( $dir_name =~ /^\// ) {
$full_path1 = "$dir_name/src/$file_name" ;
$full_path2 = "$dir_name/$file_name" ;
}
else {
$full_path1 = "$ipath/$dir_name/src/$file_name" ;
$full_path2 = "$ipath/$dir_name/$file_name" ;
}
$found_dep = 0;
# Construct full path
if ( -s $full_path1 ) {
$full_path = abs_path(dirname($full_path1)) . "/" . basename($full_path1) ;
$found_dep = 1;
}
elsif ( -s $full_path2 ) {
$full_path = abs_path(dirname($full_path2)) . "/" . basename($full_path2);
$found_dep = 1;
}
if ( $found_dep == 1 ) {
push @{$mis_depends_tree{$file}} , $full_path ;
trick_print($$sim_ref{fh}, " $full_path\n" , "debug_white" , $$sim_ref{args}{v}) ;
if ( $lang eq "y" ) {
($full_path1 = $full_path ) =~ s/\.y$/\.l/ ;
push @{$mis_depends_tree{$file}} , $full_path1 ;
}
get_depends($full_path , $sim_ref);
return(1);
}
}
}
}
return(0) ;
}
sub mis_catalog_dep ($$) {
return ;
}
1;