package CPANXR::Apache::Symbol;
use CPANXR::Apache::Util;
use CPANXR::Database;
use CPANXR::Parser qw(:constants);
use File::Spec::Functions qw(catdir);
use Data::Page;
use strict;
our %Types = (
t1 => [CONN_PACKAGE, 'packages'],
t2 => [CONN_FUNCTION, 'function calls'],
t3 => [CONN_METHOD, 'method calls'],
t3 => [CONN_MACRO, 'macros'],
t4 => [CONN_INCLUDE, 'uses'],
t5 => [CONN_DECL, 'declarations'],
t6 => [CONN_ISA, 'inheritence'],
t7 => [CONN_REF, 'references'],
t8 => [CONN_LINK, 'includes'],
t9 => [CONN_FILE, 'files'],
);
sub find {
my ($self, $r, $q) = @_;
my $symbol_id = $q->param('symbol');
my $pkg_id = $q->param('pkg');
my $current = $q->param('p') || 1;
unless($symbol_id =~ /^\d+$/) {
$r->print("Missing argument symbol");
return;
}
my $pkg = "";
if($pkg_id) {
unless($pkg_id =~ /^\d+$/) {
$r->print("Malformed argument pkg");
}
$pkg = CPANXR::Database->select_symbol($pkg_id)->[0]->[0];
}
my $symbol = CPANXR::Database->select_symbol($symbol_id)->[0]->[0];
$r->print("Looking for $symbol");
if($pkg) {
$r->print(" in package $pkg");
}
$r->print(" and found
\n");
$r->print("
\n"); my %args; # Extract limit { my @limit_types; while(my ($param, $value) = each %Types) { my $v = $q->param($param) ? 1 : 0; push @limit_types, $value->[0] if $v; } if(@limit_types) { $args{limit_types} = \@limit_types; } } # Select files matching symbol my $files = CPANXR::Database->select_files(symbol_id => $symbol_id); @$files = map { [ $symbol_id, $symbol, "", "", $_->[2], $_->[0], undef, CONN_FILE, undef, $_->[1]] } @$files; # Select connections matching symbol my $result = CPANXR::Database->select_connections(symbol_id => $symbol_id, %args); unshift @$result, @$files; $result = $self->transform($result); my $table = CPANXR::Apache::Util::Table->new($r, 4, [qw(15% 55% 15% 15%)]); $table->begin; $table->header("Type:", "File:", "Location:", "Show:"); my $page = Data::Page->new(scalar @$result, 10, $current); my ($pre_file, $pre_type) = ("",""); for($page->splice($result)) { if($pre_file ne $_->[1] || ($pre_type ne $_->[0])) { $pre_file = $_->[1]; } else { $_->[1] = ""; } if($pre_type eq $_->[0]) { $_->[0] = ""; } else { $pre_type = $_->[0]; } $table->print(@$_); } $table->end; # Write navigation my $base = "find?symbol=$symbol_id&pkg=$pkg_id"; my $base_type = ""; $base_type .= "&$_=" . ($q->param($_) ? 1 : 0) for(keys %Types); $base_type =~ s/=0/=1/g unless($base =~ /=1/); CPANXR::Apache::Util->navigator($r, $page, $base . $base_type); # Limit search $r->print(qq{"); } my @Types = ("uses", "calls", "calls", "functions", "macros", "packages", "inherits", "references", "includes", "files", ); sub transform { my ($self, $result) = @_; my $groups = {}; foreach my $item (@$result) { my $type = $Types[$item->[7]]; $groups->{$type} = {} unless(exists $groups->{$type}); if(exists $groups->{$type}->{$item->[4]}) { push @{$groups->{$type}->{$item->[4]}->{lines}}, [$item->[2], $item->[0], $item->[6], $item->[8]]; } else { $groups->{$type}->{$item->[4]} = { file_id => $item->[5], lines => [[$item->[2], $item->[0], $item->[6], $item->[8]]], }; } } my @result; foreach my $type (sort keys %$groups) { my $show_type = "$type"; while(my ($file, $entries) = each %{$groups->{$type}}) { my $show_file = $file; if(@{$entries->{lines}}) { foreach my $line (@{$entries->{lines}}) { my $show_line = ""; if($line->[0] ne "") { $show_line = qq{at line $line->[0]}; } else { $show_line = "n/a"; } my $func = ""; if($type eq 'functions') { my $pkg_id = $line->[2] || $line->[3]; my $sym_id = $line->[1]; $func = qq{Call graph}; } elsif($type eq 'packages') { $func = qq{IS-A graph}; } elsif($type eq 'files') { $func = qq{File graph}; } push @result, [$show_type, $show_file, $show_line, $func]; } } } } return \@result; } 1;
}); $r->print("