#!/usr/bin/perl -w use PPI; use strict; use Cwd 'abs_path'; my $filename = shift || die "Give me a doc!"; my $doc = PPI::Document->new($filename); my $subs = $doc->find("PPI::Statement::Sub"); my $packages = $doc->find('PPI::Statement::Package'); my @pkg_info = (['main', 0]); if ($packages ne "") { for my $pkg ( @$packages ) { my $start = $pkg->line_number; my $pkg_name = $pkg->{children}[2]; push @pkg_info, [$pkg_name, $start]; } } sub enclosing_pkg($$) { my ($start, $end) = @_; my $pkg_name = 'main'; foreach my $pkg_info (@pkg_info) { if ($pkg_info->[1] > $start) { # fn start and end can't span a "package" statement. die "Bolixed package parsing" if $pkg_info->[1] < $end; last; } $pkg_name = $pkg_info->[0]; } $pkg_name; } print abs_path($filename), ":", $/; for my $fn ( @$subs ) { my $start = $fn->line_number; my $lines = $fn =~ y/\n//; my $end = $start + $lines; my $pkg_name = enclosing_pkg($start, $end); printf "\t%s::%s: %d-%d\n", $pkg_name, $fn->name, $start, $end; }