/usr/local/CPAN/App-sh2p/App/sh2p/Here.pm
package App::sh2p::Here;
# I expect only one active here doc at a time,
# but I guess they could be in nested loops
# while read var1
# do
# while read var2
# do
# ...
# done << HERE
# ...
# HERE
# done << HERE
# ...
# HERE
# This would create a problem, since the filename
# is based on the here label - TODO
#
use strict;
use Carp;
use Scalar::Util qw(refaddr);
use App::sh2p::Utils;
our $VERSION = '0.06';
#################################################################################
my %handle;
my %name;
my %access;
my $g_last_opened_here_name;
my $g_last_opened_file_name;
my $g_write_subroutines = 0;
#################################################################################
sub store_sh2p_here_subs {
$g_write_subroutines = 1;
}
#################################################################################
# January 2009
sub abandon_sh2p_here_subs {
$g_write_subroutines = 0;
}
#################################################################################
sub get_last_here_doc {
my $name = $g_last_opened_here_name;
$g_last_opened_here_name = undef;
return $name
}
#################################################################################
sub get_last_file_name {
my @caller = caller();
print STDERR "get_last_file_name: <$g_last_opened_file_name> @caller\n";
my $name = $g_last_opened_file_name;
$g_last_opened_file_name = undef;
return $name
}
#################################################################################
sub _get_dir {
my $dir;
if (defined $ENV{SH2P_HERE_DIR}) {
$dir = $ENV{SH2P_HERE_DIR}
}
else {
$dir = '.'
}
return $dir;
}
#################################################################################
sub gen_filename {
my $name = shift;
my $dir = _get_dir();
return "$dir/$name.here";
}
#################################################################################
sub open {
my ($class, $name, $access) = @_;
my $this = bless \do{my $some_scalar}, $class;
my $key = refaddr $this;
$name {$key} = $name;
$access{$key} = $access;
$g_last_opened_here_name = $name;
my $full_name = gen_filename($name);
error_out ("Writing $full_name");
open ($handle{$key}, $access{$key}, "$full_name") ||
carp "Unable to open $full_name: $!\n";
$g_write_subroutines = 1;
return $this
}
#################################################################################
sub open_rd {
my ($class, $filename, $access) = @_;
my $this = bless \do{my $some_scalar}, $class;
my $key = refaddr $this;
$name {$key} = $filename;
$access{$key} = $access;
$g_last_opened_file_name = $filename;
$g_write_subroutines = 1;
return $this
}
#################################################################################
sub write {
my ($this, $buffer) = @_;
my $key = refaddr $this;
my $handle = $handle{$key};
print $handle ("$buffer\n") or
carp "Unable to write to $name{$key}: $!";
}
#################################################################################
sub read {
my ($this) = @_;
my $key = refaddr $this;
return <$handle{key}>
}
#################################################################################
sub close {
my ($this) = @_;
my $key = refaddr $this;
my $retn = close $handle{$key};
delete $handle{$key};
delete $name {$key};
delete $access{$key};
return $retn;
}
#################################################################################
sub DESTROY {
my ($this) = @_;
my $key = refaddr $this;
if (exists $name{$key}) {
close_here_doc ($this);
}
}
#################################################################################
sub write_here_subs {
if ($g_write_subroutines) {
$g_write_subroutines = 0;
out "";
out << 'END';
######################################################
# sh2p_read_from_handle
# Arguments:
# 1. Handle
# 2. Value of $IFS
# 3. Prompt string
# 4. List of scalar references
# Any may be undef
sub sh2p_read_from_handle {
my ($handle, $sh2p_IFS, $prompt, @refs) = @_;
return 0 if eof($handle);
if (!defined $sh2p_IFS) {
$sh2p_IFS = " \t\n";
}
if (defined $prompt) {
print $prompt
}
my $line = <$handle>;
my $sh2p_REPLY;
chomp $line;
my (@vars) = split /[$sh2p_IFS]+/, $line;
my $i;
# Assign values to variables
for ($i = 0; $i < @refs; $i++) {
if ($i > $#vars) {
${$refs[$i]} = '';
}
else {
${$refs[$i]} = $vars[$i];
}
}
# If not enough variables supplied
if ($i < @vars || !@refs) {
my $IFS1st = substr($sh2p_IFS,0,1);
$sh2p_REPLY = join $IFS1st, @vars[$i..$#vars];
}
if (@refs > 0 && defined $sh2p_REPLY) {
# Concat extra values onto the element
${$refs[-1]} .= " $REPLY";
}
return 1;
}
######################################################
sub sh2p_read_from_stdin {
my (@args) = @_;
return sh2p_read_from_handle (*STDIN, @args);
}
######################################################
{
# No 'state' variables in 5.8
my $handle;
sub sh2p_read_from_file {
my ($filename, @args) = @_;
if (!defined $handle) {
open ($handle, '<', $filename) or
die "Unable to open $filename: $!";
}
my $retn = sh2p_read_from_handle ($handle, @args);
if (!$retn) {
close $handle;
undef $handle;
}
return $retn;
}
}
######################################################
# End of subroutines added by sh2p
######################################################
END
# End of here document
}
}
#################################################################################
1;