3
0
mirror of https://github.com/pragma-/pbot.git synced 2025-10-14 15:07:22 +02:00

Core/Interpreter: improve command splitting and substitutions

This commit is contained in:
Pragmatic Software 2025-07-29 13:39:11 -07:00
parent 27db494f85
commit d5aa7f9e41
No known key found for this signature in database
GPG Key ID: CC916B6E3C84ECCE
2 changed files with 50 additions and 56 deletions

View File

@ -253,11 +253,10 @@ sub process_line($self, $from, $nick, $user, $host, $text, $tags = '', $is_comma
$processed++; $processed++;
# reset context # reset context
delete $context->{subcmd}; delete $context->{cmdstack};
delete $context->{outq};
delete $context->{pipe}; delete $context->{pipe};
delete $context->{pipe_next}; delete $context->{pipe_next};
delete $context->{command_split};
delete $context->{split_result};
delete $context->{add_nick}; delete $context->{add_nick};
} }
@ -297,7 +296,8 @@ sub interpret($self, $context) {
# check for a split command, e.g. "echo Hello ;;; echo world." # check for a split command, e.g. "echo Hello ;;; echo world."
if ($context->{command} =~ m/^(.*?)\s*(?<!\\);;;\s*(.*)/ms) { if ($context->{command} =~ m/^(.*?)\s*(?<!\\);;;\s*(.*)/ms) {
$context->{command} = $1; # command is the first half of the split $context->{command} = $1; # command is the first half of the split
$context->{command_split} = $2; # store the rest of the split, potentially containing more splits push @{$context->{cmdstack}}, $2; # store the rest of the split, potentially containing more splits
push @{$context->{outq}}, []; # add output queue to stack
} }
# convert command string to list of arguments # convert command string to list of arguments
@ -450,7 +450,10 @@ sub interpret($self, $context) {
$arguments =~ s/&\s*\{\Q$command\E\}/&{subcmd}/; $arguments =~ s/&\s*\{\Q$command\E\}/&{subcmd}/;
# add it to the list of substituted commands # add it to the list of substituted commands
push @{$context->{subcmd}}, "$keyword $arguments"; push @{$context->{cmdstack}}, "$keyword $arguments";
# add output queue to stack
push @{$context->{outq}}, [];
# FIXME: quick-and-dirty hack to fix $0. # FIXME: quick-and-dirty hack to fix $0.
# Without this hack `pet &{echo dog}` will output `You echo # Without this hack `pet &{echo dog}` will output `You echo
@ -638,12 +641,21 @@ sub handle_result($self, $context, $result = $context->{result}) {
return 0; return 0;
} }
# finish command substitution # process next command in stack
if (exists $context->{subcmd}) { if (exists $context->{cmdstack}) {
my $command = pop @{$context->{subcmd}}; my $command = pop @{$context->{cmdstack}};
if (@{$context->{subcmd}} == 0 or $context->{alldone}) { if (@{$context->{cmdstack}} == 0 or $context->{alldone}) {
delete $context->{subcmd}; delete $context->{cmdstack};
}
if ($command =~ m/&\{subcmd\}/) {
# finish command substitution
my $output = pop @{$context->{outq}};
$output = join " ", @$output;
if (length $output) {
$result = "$output $result";
} }
if ($command =~ s/\b(an?)(\s+)&\{subcmd\}/&{subcmd}/i) { if ($command =~ s/\b(an?)(\s+)&\{subcmd\}/&{subcmd}/i) {
@ -661,6 +673,9 @@ sub handle_result($self, $context, $result = $context->{result}) {
} else { } else {
$command =~ s/&\{subcmd\}/$result/; $command =~ s/&\{subcmd\}/$result/;
} }
} else {
push @{$context->{outq}->[$#{$context->{outq}}]}, $result;
}
if (not $context->{alldone}) { if (not $context->{alldone}) {
$context->{command} = $command; $context->{command} = $command;
@ -676,43 +691,22 @@ sub handle_result($self, $context, $result = $context->{result}) {
$result = "$context->{result_prefix} $result"; $result = "$context->{result_prefix} $result";
} }
# finish command split # join output queue
if ($context->{command_split}) { if (exists $context->{outq}) {
my $botnick = $self->{pbot}->{conn}->nick;
# update contextual command with next command in split while (my $outq = pop @{$context->{outq}}) {
$context->{command} = delete $context->{command_split}; $outq = join " ", @$outq;
# reformat result to be more suitable for joining together # reformat result to be more suitable for joining together
$result =~ s!^/say !\n!i;
$result =~ s!^/me !\n* $botnick !i;
if (not length $context->{split_result}) {
$result =~ s/^\n//;
$context->{split_result} = $result;
} else {
$context->{split_result} .= $result;
}
delete $context->{ref_from};
delete $context->{add_nick};
$context->{result} = $self->interpret($context);
$self->handle_result($context);
return 0;
}
# join command split
if ($context->{split_result}) {
my $botnick = $self->{pbot}->{conn}->nick; my $botnick = $self->{pbot}->{conn}->nick;
# reformat result to be more suitable for joining together
$result =~ s!^/say !\n!i $result =~ s!^/say !\n!i
|| $result =~ s!^/me !\n* $botnick !i || $result =~ s!^/me !\n * $botnick !i
|| $result =~ s!^!\n!; || $result =~ s!^!\n!;
$result = $context->{split_result} . $result; $result = "$outq$result";
delete $context->{split_result}; $result =~ s/^\n+//;
}
delete $context->{outq};
} }
# nothing more to do here if we have no result or keyword # nothing more to do here if we have no result or keyword

View File

@ -25,8 +25,8 @@ use PBot::Imports;
# These are set by the /misc/update_version script # These are set by the /misc/update_version script
use constant { use constant {
BUILD_NAME => "PBot", BUILD_NAME => "PBot",
BUILD_REVISION => 4878, BUILD_REVISION => 4879,
BUILD_DATE => "2025-07-20", BUILD_DATE => "2025-07-29",
}; };
sub initialize {} sub initialize {}