Revision: 1199
Author: [email protected]
Date: Mon Apr 26 02:22:36 2010
Log: Assorted refactorings and cleanup.

http://code.google.com/p/perl-devel-nytprof/source/detail?r=1199

Modified:
 /trunk/bin/nytprofhtml
 /trunk/lib/Devel/NYTProf/Reader.pm

=======================================
--- /trunk/bin/nytprofhtml      Wed Apr 21 06:25:45 2010
+++ /trunk/bin/nytprofhtml      Mon Apr 26 02:22:36 2010
@@ -16,6 +16,7 @@
 use Getopt::Long;
 use List::Util qw(sum max);
 use File::Copy;
+use File::Path qw(rmtree);

 use Devel::NYTProf::Reader;
 use Devel::NYTProf::Core;
@@ -48,58 +49,68 @@

 my @on_ready_js;

-my %opt = (
-    file => 'nytprof.out',
-    out  => 'nytprof',
-);
-GetOptions(\%opt, qw/file|f=s delete|d out|o=s lib|l=s help|h open/)
-    or do {
-        usage();
-        exit 1;
-    };
-
-if (defined($opt{help})) {
-    usage();
-    exit;
-}
-
-# handle file selection option
-if (!-r $opt{file}) {
-    die "$0: Unable to access $opt{file}\n";
+GetOptions(
+    'file|f=s'   => \(my $opt_file = 'nytprof.out'),
+    'lib|l=s'   => \my $opt_lib,
+    'out|o=s'   => \(my $opt_out = 'nytprof'),
+    'delete|d!' => \my $opt_delete,
+    'open!'     => \my $opt_open,
+    'help|h'    => sub { exit usage() },
+    'profself!'     => sub {
+        # profile nytprofhtml itself
+        my $profself = "nytprof-nytprofhtml.out";
+        $ENV{NYTPROF} .= ":file=$profself";
+        require Devel::NYTProf;
+        END { warn "Profile of $0 written to $profself\n" if $profself; }
+    },
+) or do { exit usage(); };
+
+
+sub usage {
+    print <<END;
+usage: [perl] nytprofhtml [opts]
+ --file <file>, -f <file> Read profile data from the specified file [default: nytprof.out] + --out <dir>, -o <dir> Write report files to this directory [default: nytprof]
+ --delete,      -d         Delete any old report files in <dir> first
+ --lib <lib>,   -l <lib>   Add <lib> to the beginning of \...@inc
+ --help,        -h         Print this message
+
+This script of part of the Devel::NYTProf distribution.
+See http://search.cpan.org/dist/Devel-NYTProf/ for details and copyright.
+END
+    return 1;
 }

-# handle handle output location
-if (!-e $opt{out}) {
-
+
+# handle handle output location
+if (!-e $opt_out) {
     # will be created
 }
-elsif (!-d $opt{out}) {
-    die "$0: Specified output directory `$opt{out}' is a file. whoops!\n";
-}
-elsif (!-w $opt{out}) {
-    die "$0: Unable to write to output directory `$opt{out}'\n";
-}
-
-# handle deleting old db's
-if (defined($opt{'delete'})) {
-    _delete();
+elsif (!-d $opt_out) {
+ die "$0: Specified output directory '$opt_out' already exists as a file!\n";
+}
+elsif (!-w $opt_out) {
+    die "$0: Unable to write to output directory '$opt_out'\n";
+}
+else {
+    if (defined($opt_delete)) {
+        print "Deleting existing $opt_out directory\n";
+        rmtree($opt_out);
+    }
 }

 # handle custom lib path
-if (defined($opt{lib})) {
-    if (-d $opt{lib}) {
-        unshift(@INC, $opt{lib});
-    }
-    else {
-        die "$0: Specified lib directory `$opt{lib}' does not exist.\n";
-    }
+if (defined($opt_lib)) {
+    warn "$0: Specified lib directory '$opt_lib' does not exist.\n"
+        unless -d $opt_lib;
+    require lib;
+    lib->import($opt_lib);
 }

-print "Generating report...\n";
-my $reporter = new Devel::NYTProf::Reader($opt{file});
+my $reporter = new Devel::NYTProf::Reader($opt_file);

 # place to store this
-$reporter->output_dir($opt{out});
+$reporter->output_dir($opt_out);

 # set formatting for html
 $reporter->set_param(
@@ -128,7 +139,13 @@
             [ "Statements", sprintf "Executed %d statements in %s",
$fi->sum_of_stmts_count, fmt_time($fi->sum_of_stmts_time) ],
         );
-        # XXX if string eval then add link to calling location
+        if ($fi->is_eval) {
+            push @intro_rows, [
+                "Eval Invoked At", sprintf q{<a %s>%s line %d</a>},
+                    $reporter->href_for_file($fi->eval_fi, $fi->eval_line),
+                    _escape_html($fi->eval_fi->filename), $fi->eval_line
+            ];
+        }

         my $intro_table = join "\n", map {
sprintf q{<tr><td class="h">%s</td><td align="left">%s</td></tr>}, @$_
@@ -262,9 +279,10 @@
             unshift @hints, ($is_opcode) ? 'opcode' : 'xsub';
         }

-        my $href = $reporter->href_for_sub($subname);
         $sub_links .= sprintf qq{%*s<a %s>%s</a>%s</span></td>},
-            $max_pkg_name_len+2, $pkg, $href, $subr,
+            $max_pkg_name_len+2, $pkg,
+            $reporter->href_for_sub($subname),
+            $subr,
             (@hints) ? "&nbsp;(".join(", ",@hints).")" : "";

         $sub_links .= "</tr>\n";
@@ -456,9 +474,9 @@
             # remove @INC prefix from paths
             $line_desc =~ s/$inc_path_regex//g;

- my $href = $reporter->href_for_file($caller_fi, $line) | | 'unknown';
+            my $href = $reporter->href_for_file($caller_fi, $line);
             push @prologue,
-                sprintf q{# %*s times%s%s at <a href="%s">%s</a>%s},
+                sprintf q{# %*s times%s%s at <a %s>%s</a>%s},
                 length($max_calls), $count, $times, $subname, $href,
                 $line_desc, $avg_time;
             $prologue[-1] =~ s/^(# +)1 times/$1   once/;  # better English
@@ -533,8 +551,7 @@
                 $what .= "s";
             }

-            my $href = $reporter->href_for_file($eval_fi, undef);
- my $link = ($href) ? sprintf(q{<a href="%s">%s</a>}, $href, $what) : $what; + my $link = sprintf(q{<a %s>%s</a>}, $reporter->href_for_file($eval_fi), $what); my $html = sprintf qq{%s# spent %s executing statements in %s%s%s},
                 $ws, fmt_time($sum_of_stmts_time+$nest_eval_time, 5),
($merged_fids) ? sprintf("%d ",1+scalar @$merged_fids) : '',
@@ -564,7 +581,7 @@

 output_js_files($reporter);

-open_browser_on("$opt{out}/index.html") if $opt{open};
+open_browser_on("$opt_out/index.html") if $opt_open;

 exit 0;

@@ -577,8 +594,8 @@
     my ($r, $filename, $sortby) = @_;
     my $profile = $reporter->{profile};

-    open my $fh, '>', "$opt{out}/$filename"
-        or croak "Unable to open file $opt{out}/$filename: $!";
+    open my $fh, '>', "$opt_out/$filename"
+        or croak "Unable to open file $opt_out/$filename: $!";

     print $fh get_html_header("Subroutine Index - NYTProf");
print $fh get_page_header(profile => $profile, title => "Performance Profile Subroutine Index");
@@ -600,8 +617,8 @@
     my $profile = $reporter->{profile};

     ###
-    open my $fh, '>', "$opt{out}/$filename"
-        or croak "Unable to open file $opt{out}/$filename: $!";
+    open my $fh, '>', "$opt_out/$filename"
+        or croak "Unable to open file $opt_out/$filename: $!";

     print $fh get_html_header();
print $fh get_page_header(profile => $profile, title => "Performance Profile Index", skip_link_to_index=>1);
@@ -911,8 +928,8 @@
     my ($r, $filename, $title, $area_sub) = @_;
     my $profile = $reporter->{profile};

-    open(my $fh, '>', "$opt{out}/$filename")
-        or croak "Unable to open file $opt{out}/$filename: $!";
+    open(my $fh, '>', "$opt_out/$filename")
+        or croak "Unable to open file $opt_out/$filename: $!";

     $title ||= "Subroutine Time Treemap";
print $fh get_html_header("$title - NYTProf", { add_jit => "Treemap" });
@@ -956,7 +973,7 @@
     my $profile = $reporter->{profile};
     my $subinfos = $profile->subname_subinfo_map;

-    my $dot_file = "$opt{out}/$filename";
+    my $dot_file = "$opt_out/$filename";
     open my $fh, '>', $dot_file
         or croak "Unable to open file $dot_file: $!";

@@ -1078,7 +1095,7 @@
     my ($profile) = @_;
     # find the js, gif, css etc files installed with Devel::NYTProf
     (my $lib = $INC{"Devel/NYTProf/Data.pm"}) =~ s/\/Data\.pm$//;
-    _copy_dir("$lib/js", "$opt{out}/js");
+    _copy_dir("$lib/js", "$opt_out/js");
 }

 sub _copy_dir {
@@ -1222,10 +1239,7 @@
         push @t_stmt_time, $time;

         my $rep_links = join '&nbsp;&bull;&nbsp;', map {
-            my $href = $reporter->href_for_file($fi, undef, $_);
-            ($href)
-                ? sprintf(qq{<a href="%s">%s</a>}, $href, $_)
-                : ()
+ sprintf(qq{<a %s>%s</a>}, $reporter->href_for_file($fi, undef, $_), $_)
         } qw(line block sub);
         print $fh "<td>$rep_links</td>";

@@ -1325,31 +1339,6 @@

     return qq{<td class="$class">$fmt_val</td>};
 }
-
-# Delete the previous database/directory if it exists
-sub _delete {
-    if (-d $opt{out}) {
-        print "Deleting $opt{out}\n";
-        unlink glob($opt{out} . "/*");
-        unlink glob($opt{out} . "/.*");
-        rmdir $opt{out} or confess "Delete of $opt{out} failed: $!\n";
-    }
-}
-
-sub usage {
-    print <<END
-usage: [perl] nytprofhtml [opts]
- --file <file>, -f <file> Use the specified file as Devel::NYTProf database
-                            file. [default: ./nytprof.out]
- --out <dir>,   -o <dir>   Place generated files here [default: ./nytprof]
- --delete,      -d         Delete the old nytprofhtml output [uses --out]
- --lib,         -l         Add a path to the beginning of \...@inc
- --help,        -h         Print this message
-
-This script of part of the Devel::NYTProf distribution.
-See http://search.cpan.org/dist/Devel-NYTProf/ for details and copyright.
-END
-}


# return an html string with buttons for switching between profile levels of detail
=======================================
--- /trunk/lib/Devel/NYTProf/Reader.pm  Wed Apr 21 06:41:34 2010
+++ /trunk/lib/Devel/NYTProf/Reader.pm  Mon Apr 26 02:22:36 2010
@@ -161,6 +161,18 @@
     return $self->{current_level} || 'line';
 }

+sub fname_for_fileinfo {
+    my ($self, $fi, $level) = @_;
+    $level ||= $self->current_level;
+
+    my $fname = html_safe_filename($fi->filename_without_inc);
+    $fname .= "-".$fi->fid;
+    $fname .= "-$level" if $level;
+
+    return $fname;
+}
+
+
 ##
 sub _generate_report {
     my $self = shift;
@@ -173,21 +185,8 @@

#$profile->dump_profile_data({ filehandle => \*STDERR, separator=>"\t", });

-    # pre-calculate some data so it can be cross-referenced
     foreach my $fi (@all_fileinfos) {

-        # discover file path
-        my $fname = html_safe_filename($fi->filename_without_inc);
-        $fname .= "-".$fi->fid;
-        $fname .= "-$LEVEL" if $LEVEL;
-
-        my $meta = $fi->meta;
-        $meta->{html_safe} = $fname;
-        $meta->{$LEVEL}->{html_safe} = $fname;
-    }
-
-    foreach my $fi (@all_fileinfos) {
-
         # we only generate line-level reports for evals
         # for efficiency and because some data model editing only
         # is only implemented for line-level data
@@ -293,7 +292,7 @@

# the output file name that will be open later. Not including directory at this time.
         # keep here so that the variable replacement subs can get at it.
-        my $fname = $meta->{html_safe} . $self->{suffix};
+        my $fname = $self->fname_for_fileinfo($fi) . $self->{suffix};

         # localize header and footer for variable replacement
my $header = $self->get_param('header', [$profile, $fi, $fname, $LEVEL]);
@@ -446,24 +445,27 @@
 }


-sub href_for_file {
+sub url_for_file {
     my ($self, $file, $anchor, $level) = @_;
-    $level ||= $self->current_level;

     my $fi = $self->{profile}->fileinfo_of($file);
-    return undef if $fi->is_fake;
-
-    $level = 'line' if $fi->is_eval;
-
-    my $href = $fi->meta->{$level}->{html_safe};
-    $href &&= $href.'.html';
-    $href .= "#$anchor" if defined $anchor;
-
-    return $href;
+    #return "" if $fi->is_fake;
+
+    my $url = $self->fname_for_fileinfo($fi, $level);
+    $url .= '.html';
+    $url .= "#$anchor" if defined $anchor;
+
+    return $url;
+}
+
+sub href_for_file {
+    my $url = shift->url_for_file(@_);
+    return qq{href="$url"} if $url;
+    return $url;
 }


-sub href_for_sub {
+sub url_for_sub {
     my ($self, $sub, %opts) = @_;
     my $profile = $self->{profile};

@@ -471,7 +473,7 @@
     if (!$first) {
         if (not defined $first) {
warn("No file line range data for sub '$sub' (perhaps an xsub)\n") - unless our $href_for_sub_no_data_warn->{$sub}++; # warn just once + unless our $url_for_sub_no_data_warn->{$sub}++; # warn just once
             return "";
         }
         # probably xsub
@@ -480,14 +482,13 @@
         # use sanitized subname as label
         ($first = $sub) =~ s/\W/_/g;
     }
-
-    my $html_safe = $fi->meta->{html_safe} ||= do {
-        # warn, just once, and use a default value
-        warn "Sub '$sub' file '$file' (fid $fid) has no html_safe value\n";
-        "unknown";
-    };
-    $html_safe = ($opts{in_this_file}) ? "" : "$html_safe.html";
-    return sprintf q{href="%s#%s"}, $html_safe, $first;
+    return $self->url_for_file($fi, $first);
+}
+
+sub href_for_sub {
+    my $url = shift->url_for_sub(@_);
+    return qq{href="$url"} if $url;
+    return $url;
 }


--
You've received this message because you are subscribed to
the Devel::NYTProf Development User group.

Group hosted at:  http://groups.google.com/group/develnytprof-dev
Project hosted at:  http://perl-devel-nytprof.googlecode.com
CPAN distribution:  http://search.cpan.org/dist/Devel-NYTProf

To post, email:  [email protected]
To unsubscribe, email:  [email protected]

Reply via email to