1 # This file is part of the graph-includes package
3 # (c) 2005 Yann Dirson <ydirson@altern.org>
4 # Distributed under version 2 of the GNU GPL.
6 package graphincludes
::project
;
10 use graphincludes
::params
;
13 use graphincludes
::graph
;
15 use File
::Spec
::Functions
qw(catfile catpath splitdir splitpath);
16 use Hash
::Util
qw(lock_keys);
18 # set_language: class method that sets the language to be used when extracting deps.
19 # This is a hack, which does not allow to mix several languages in a single project.
20 # It is only a temporary measure that allows support for languages other than C/C++.
25 my $langmodule = "graphincludes::extractor::" . $_language;
26 eval "require $langmodule" or die "cannot load $langmodule from " . join ':', @INC;
27 push @ISA, $langmodule;
33 my $prefixstrip = $args{prefixstrip
};
34 my @files = @
{$args{files
}}; # take a copy of @ARGV
37 # if (defined $_language) {
38 # $self = ("graphincludes::extractor::" . $_language)->new;
41 $self->{GRAPHS
} = [ new graphincludes
::graph
]; # stack of graphs for the different levels
42 $self->{GRAPHS
}[0]->init_nodes(\
@files);
44 $self->{PFXSTRIP
} = $prefixstrip;
45 $self->{SPECIALEDGES
} = {};
46 $self->{IGNOREDEDGES
} = {}; # to be computed in getdeps
47 $self->{REPORT
} = { HDR
=> {},
51 bless ($self, $class);
60 $self->{GRAPHS
}[0]{EDGES
} = $self->getdeps($self->{GRAPHS
}[0]{NODES
});
62 $self->{GRAPHS
}[1] = new graphincludes
::graph
;
63 $self->{GRAPHS
}[1]->init_nodes ($self->_level1nodes(@
{$self->{GRAPHS
}[0]{NODES
}}));
65 # FIXME: level1 deps ?
70 my ($file,$level) = @_;
75 # FIXME: should register link to lower-level
80 foreach my $file (@files) {
81 my $label = $self->filelabel($file);
82 push @
{$nodes{$label}}, $file;
89 my ($dst, @path) = @_;
91 print STDERR
"Trying to locate \`$dst'\n" if $graphincludes::params
::debug
;
94 my ($dstpath, $strip, $srcpath) = @_;
95 catfile
(@
$srcpath[0..($#$srcpath-$strip)], @$dstpath);
98 (undef, my $dstdir, my $filename) = splitpath
($dst);
99 my @dstpath = (splitdir
($dstdir), $filename);
100 # count number of leading "../" in the #include reference
102 while ($dstpath[0] eq '..') {
103 $strip++; shift @dstpath;
105 # find the file in @path
107 foreach my $dir (@path) {
108 my @srcpath = splitdir
($dir);
109 if (defined($dstfile = fullpath
(\
@dstpath,$strip,\
@srcpath)) and
110 grep { $_ eq $dstfile } @
{$self->{GRAPHS
}[0]{NODES
}}) {
111 print STDERR
" Found from $dir ($dstfile)\n" if $graphincludes::params
::debug
;
114 print STDERR
" Not from $dir ($dstfile)\n" if $graphincludes::params
::debug
;
119 return $dstfile; # can be undef !
123 my ($file, @path) = @_;
124 foreach my $dir (@path) {
125 my $f = catpath
('', $dir, $file);
133 my ($deps, $src, $dst) = @_;
135 my $orignode = $self->filelabel($src);
136 my $destnode = $self->filelabel($dst);
137 if (defined $self->{IGNOREDDEPS
}->{$src}->{$dst}) {
138 print STDERR
"ignoring $src -> $dst\n" if $graphincludes::params
::debug
;
139 $self->{IGNOREDEDGES
}->{$orignode}->{$destnode} =
140 $self->{IGNOREDDEPS
}->{$src}->{$dst};
142 if (defined $deps->{$orignode}->{$destnode}) {
143 $deps->{$orignode}->{$destnode} ++;
145 $deps->{$orignode}->{$destnode} = 1;
149 sub record_missed_dep
{
151 my ($src, $dst) = @_;
153 if (defined _fileexists
($dst, @graphincludes::params
::sysinclpath
)) {
154 # list as system include
155 $self->{REPORT
}->{SYS
}->{$dst} = 1;
157 # list as unknown header
158 push @
{$self->{REPORT
}->{HDR
}->{$dst}}, $src;
164 my ($src, $dst) = @_;
166 my $attrs = $self->{SPECIALEDGES
}->{$src}->{$dst};
168 if (defined $attrs) {