/usr/local/CPAN/HTML-WebMake/HTML/WebMake/PerlCode.pm
# PerlCode; allow arbitrary perl code be embedded in a WebMake file.
package HTML::WebMake::PerlCode;
use Carp;
use strict;
use HTML::WebMake::Main;
use HTML::WebMake::PerlCodeLibrary;
use vars qw{
@ISA $CAN_USE_IO_STRING
$GlobalSelf @PrevSelves %SORT_SUBS
};
@ISA = qw();
###########################################################################
sub new ($$) {
my $class = shift;
$class = ref($class) || $class;
my ($main) = @_;
my $self = {
'main' => $main,
};
bless ($self, $class);
$self;
}
sub can_use_io_string {
if (defined $CAN_USE_IO_STRING) { return $CAN_USE_IO_STRING; }
$CAN_USE_IO_STRING = 0;
eval q{
require IO::String; $CAN_USE_IO_STRING = 1; 1;
};
return $CAN_USE_IO_STRING;
}
sub new_io_string {
eval q{
return new IO::String ();
};
}
sub dbg { HTML::WebMake::Main::dbg (@_); }
# -------------------------------------------------------------------------
sub interpret {
my ($self, $type, $str, $defunderscoreval) = @_;
my ($ret);
local ($_) = $defunderscoreval;
if (!defined ($_)) { $_ = ''; }
if ($self->{main}->{paranoid}) {
return "\n(Paranoid mode on - perl code evaluation prohibited.)\n";
}
# note that both $self and $_ are available from within evaluated
# perl code.
$self->enter_perl_call();
if ($type ne "perlout") {
$ret = eval 'package main; '.$str;
} else {
if (!can_use_io_string()) {
warn "<{perlout}> code failed: IO::String module not available\n";
} else {
my $outhandle = new_io_string();
$ret = eval 'package main; select $outhandle; '.$str;
if (defined($ret)) {
$ret = ${$outhandle->string_ref()};
chomp $ret;
}
select STDOUT;
$outhandle = undef;
}
}
$self->exit_perl_call();
if (!defined $ret) {
warn "<{perl}> code failed: $@\nCode: $str\n";
$ret = '';
}
$ret;
}
sub enter_perl_call {
my ($self) = @_;
push (@PrevSelves, $GlobalSelf); $GlobalSelf = $self;
}
sub exit_perl_call {
my ($self) = @_;
$GlobalSelf = pop (@PrevSelves);
}
# -------------------------------------------------------------------------
# get and eval() a sort subroutine for the given sorting criteria.
# stores cached sort sub { } refs in the %SORT_SUBS global array to
# avoid re-evaluating the same piece of perl code repeatedly.
#
sub get_sort_sub {
my ($self, $sortstr) = @_;
if (!defined $SORT_SUBS{$sortstr}) {
my $sortsubstr = $self->{main}->{metadata}->string_to_sort_sub ($sortstr);
my $sortsub = eval $sortsubstr;
$SORT_SUBS{$sortstr} = $sortsub;
}
$SORT_SUBS{$sortstr};
}
# -------------------------------------------------------------------------
1;