Viewing file: find_naughty.pl (3.08 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#!/usr/bin/perl -w use strict;
# Walk through a perl script and look for 'naughty match variables' # $`, $&, and $', which may cause poor performance. # # usage: # find_naughty file1 [file2 [...]] # find_naughty <file.pl # # Author: Steve Hancock, July 2003 # # TODO: # - recursive processing might be nice # # Inspired by the discussion of naughty match variables at: # http://www.perlmonks.org/index.pl?node_id=276549 # use Getopt::Std; use IO::File; $| = 1; use vars qw($opt_h); my $usage = <<EOM; usage: find_naughty file1 [file2 [...]] find_naughty <file.pl EOM getopts('h') or die "$usage"; if ($opt_h) { die $usage }
unless (@ARGV) { unshift @ARGV, '-' } # stdin foreach my $source (@ARGV) { PerlTokenSearch::find_naughty( _source => $source, ); }
##################################################################### # # The PerlTokenSearch package is an interface to perltidy which accepts a # source filehandle and looks for selected variables. # # It works by making a callback object with a write_line() method to # receive tokenized lines from perltidy. # # Usage: # # PerlTokenSearch::find_naughty( # _source => $fh, # required source # ); # # _source is any source that perltidy will accept, including a # filehandle or reference to SCALAR or ARRAY # #####################################################################
package PerlTokenSearch; use Carp; use Perl::Tidy;
sub find_naughty {
my %args = ( @_ ); print "Testing File: $args{_source}\n";
# run perltidy, which will call $formatter's write_line() for each line my $err=perltidy( 'source' => $args{_source}, 'formatter' => bless( \%args, __PACKAGE__ ), # callback object 'argv' => "-npro -se", # -npro : ignore .perltidyrc, # -se : errors to STDOUT ); if ($err) { die "Error calling perltidy\n"; } }
sub write_line {
# This is called back from perltidy line-by-line # We're looking for $`, $&, and $' my ( $self, $line_of_tokens ) = @_; my $source = $self->{_source};
# pull out some stuff we might need my $line_type = $line_of_tokens->{_line_type}; my $input_line_number = $line_of_tokens->{_line_number}; my $input_line = $line_of_tokens->{_line_text}; my $rtoken_type = $line_of_tokens->{_rtoken_type}; my $rtokens = $line_of_tokens->{_rtokens}; chomp $input_line;
# skip comments, pod, etc return if ( $line_type ne 'CODE' );
# loop over tokens looking for $`, $&, and $' for ( my $j = 0 ; $j < @$rtoken_type ; $j++ ) {
# we only want to examine token types 'i' (identifier) next unless $$rtoken_type[$j] eq 'i';
# pull out the actual token text my $token = $$rtokens[$j];
# and check it if ( $token =~ /^\$[\`\&\']$/ ) { print STDERR "$source:$input_line_number: $token\n"; } } }
# optional routine, called once after the last line of a file sub finish_formatting { my $self = shift; return; }
|