Smart-Comments
view release on metacpan or search on metacpan
lib/Smart/Comments.pm view on Meta::CPAN
package Smart::Comments;
$Smart::Comments::VERSION = '1.06';
use 5.008;
use warnings;
use strict;
use Carp;
use List::Util qw(sum);
use Filter::Simple;
my $maxwidth = 69; # Maximum width of display
my $showwidth = 35; # How wide to make the indicator
my $showstarttime = 6; # How long before showing time-remaining estimate
my $showmaxtime = 10; # Don't start estimate if less than this to go
my $whilerate = 30; # Controls the rate at which while indicator grows
my $minfillwidth = 5; # Fill area must be at least this wide
my $average_over = 5; # Number of time-remaining estimates to average
my $minfillreps = 2; # Minimum size of a fill and fill cap indicator
my $forupdatequantum = 0.01; # Only update every 1% of elapsed distance
# Synonyms for asserts and requirements...
my $require = qr/require|ensure|assert|insist/;
my $check = qr/check|verify|confirm/;
# Horizontal whitespace...
my $hws = qr/[^\S\n]/;
# Optional colon...
my $optcolon = qr/$hws*;?/;
# Automagic debugging as well...
my $DBX = '$DB::single = $DB::single = 1;';
# Implement comments-to-code source filter...
FILTER {
shift; # Don't need the package name
s/\r\n/\n/g; # Handle win32 line endings
# Default introducer pattern...
my $intro = qr/#{3,}/;
# Handle args...
my @intros;
while (@_) {
my $arg = shift @_;
if ($arg =~ m{\A -ENV \Z}xms) {
my $env = $ENV{Smart_Comments} || $ENV{SMART_COMMENTS}
|| $ENV{SmartComments} || $ENV{SMARTCOMMENTS}
;
return if !$env; # i.e. if no filtering
if ($env !~ m{\A \s* 1 \s* \Z}xms) {
unshift @_, split m{\s+|\s*:\s*}xms, $env;
}
}
else {
push @intros, $arg;
}
}
if (my @unknowns = grep {!/$intro/} @intros) {
croak "Incomprehensible arguments: @unknowns\n",
"in call to 'use Smart::Comments'";
}
# Make non-default introducer pattern...
if (@intros) {
$intro = '(?-x:'.join('|',@intros).')(?!\#)';
}
# Preserve DATA handle if any...
if (s{ ^ __DATA__ \s* $ (.*) \z }{}xms) {
no strict qw< refs >;
my $DATA = $1;
open *{caller(1).'::DATA'}, '<', \$DATA or die "Internal error: $!";
}
# Progress bar on a for loop...
s{ ^ $hws* ( (?: [^\W\d]\w*: \s*)? for(?:each)? \s* (?:my)? \s* (?:\$ [^\W\d]\w*)? \s* ) \( ([^;\n]*?) \) \s* \{
[ \t]* $intro \s (.*) \s* $
}
{ _decode_for($1, $2, $3) }xgem;
# Progress bar on a while loop...
s{ ^ $hws* ( (?: [^\W\d]\w*: \s*)? (?:while|until) \s* \( .*? \) \s* ) \{
[ \t]* $intro \s (.*) \s* $
}
{ _decode_while($1, $2) }xgem;
# Progress bar on a C-style for loop...
s{ ^ $hws* ( (?: [^\W\d]\w*: \s*)? for \s* \( .*? ; .*? ; .*? \) \s* ) \{
$hws* $intro $hws (.*) $hws* $
}
{ _decode_while($1, $2) }xgem;
# Requirements...
s{ ^ $hws* $intro [ \t] $require : \s* (.*?) $optcolon $hws* $ }
{ _decode_assert($1,"fatal") }gemx;
# Assertions...
s{ ^ $hws* $intro [ \t] $check : \s* (.*?) $optcolon $hws* $ }
{ _decode_assert($1) }gemx;
# Any other smart comment is a simple dump.
# Dump a raw scalar (the varname is used as the label)...
s{ ^ $hws* $intro [ \t]+ (\$ [\w:]* \w) $optcolon $hws* $ }
{Smart::Comments::_Dump(pref=>q{$1:},var=>[$1]);$DBX}gmx;
# Dump a labelled scalar...
s{ ^ $hws* $intro [ \t] (.+ :) [ \t]* (\$ [\w:]* \w) $optcolon $hws* $ }
{Smart::Comments::_Dump(pref=>q{$1},var=>[$2]);$DBX}gmx;
# Dump a raw hash or array (the varname is used as the label)...
( run in 1.874 second using v1.01-cache-2.11-cpan-71847e10f99 )