Astro-satpass
view release on metacpan or search on metacpan
script/satpass view on Meta::CPAN
# Pull the namespace off the command spec. We make use
# of the $cmdspec argument later as a macro name, since
# with the 'core.' on the front it will be invalid, and
# force the use of the built-in.
(my $verb = $cmdspec) =~ s/^core\.//;
$verb = $alias{$verb} if $alias{$verb};
# Parse the line, pulling off output redirection as we go.
my $redout = '';
my @args = parse_line ('\s+', $cmdquote{$verb} || 0, $rest);
$rest && !@args and do {
warn <<eod;
Error - Malformed command failed to parse:
$rest
eod
next;
};
{ # Local symbol block for hacking pipe off commands
my @pipe;
@args = map {
(@pipe && !$redout) ? do {push @pipe, $_; ()} :
m/^([>|])/ ?
$1 eq '|' ? do {push @pipe, $_; ()} :
do {$redout = $_; ()} :
$redout =~ m/^>+$/ ? do {$redout .= $_; ()} :
$_} @args;
@pipe and $redout = join ' ', @pipe;
} # End local symbol block.
# Do pseudo tilde expansion.
eval {
$redout =~ s/^(>+)(~.*)/ $1 . _tilde_expand ($2) /e;
1;
} or do {
warn $@;
next;
};
# Special-case 'exit' to drop out of the input loop.
$verb eq 'exit' and last;
# Arbitrarily disallow syntactically invalid commands.
$verb =~ m/^_/ || $verb =~ m/\W/ and do {
warn <<eod;
Error - Verb '$verb' not recognized.
eod
next;
};
# Parse any command options present. Note that GetOptions is
# configured to pass any unrecognized options because otherwise
# our relative time format would confuse it.
%cmdopt = ();
{ # Begin local symbol block.
local @ARGV = @args;
Getopt::Long::Configure (@{$cmdconfig{$verb} ||= ['permute']});
GetOptions (\%cmdopt, qw{clipboard debug time}, @{$cmdlgl{$verb} ||= []});
@args = @ARGV;
}
$cmdopt{_redirection} = $cmdopt{clipboard} ? '-clipboard' : $redout;
# Preserve our current output, and redirect as and if specified.
if ($cmdopt{clipboard}) {
$redout = '';
my $fh = eval {IO::Clipboard->new ()};
$@ and do {warn $@; next;};
select ($fh) or die <<eod;
Error - Failed to redirect output to clipboard.
$!
eod
}
elsif ($redout) {
open (my $fh, $redout) or do {warn <<eod; next};
Error - Failed to open '$redout'
$!
eod
select ($fh) or die <<eod;
Error - Failed to redirect output to $redout.
$!
eod
}
# Record start time if required.
$frame[$#frame]{timing} = {
command => $buffer,
start => _time (),
} if $cmdopt{time};
# If our command is a macro, build an input stream from it, and
# pass the results to the source() command. We use $cmdspec
# because it contains the namespace 'core.' if it was specified,
# and therefore cannot match any macro name.
my $error; # Status from command execution.
if ($macro{$cmdspec}) {
my $cmd = join "\n", @{$macro{$cmdspec}};
source (_memio ('<', \$cmd), @args);
$frame[$#frame]{macro}{$cmdspec} = $macro{$verb};
delete $macro{$cmdspec};
}
# Else, if there exists a subroutine named after the command,
# call it, fielding any exceptions thrown and turning them into
# warnings.
elsif (my $code = __PACKAGE__->can($verb)) {
_parse_time_reset (); # Reset relative time base to last explicit
local $SIG{INT} = sub {die "\n$interrupted\n"};
eval {$code->(@args)};
$error = $@;
}
# Else, complain about the unrecognized verb.
( run in 0.529 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )