3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-17 09:29:30 +01:00

Fix white-space handling; add suppress-no-output

This commit is contained in:
Pragmatic Software 2024-11-03 19:26:56 -08:00
parent 1f232a9455
commit 4c866d39b6
No known key found for this signature in database
GPG Key ID: CC916B6E3C84ECCE
6 changed files with 166 additions and 63 deletions

View File

@ -16,60 +16,75 @@ our @EXPORT = qw(split_line);
# splits line into arguments separated by unquoted whitespace. # splits line into arguments separated by unquoted whitespace.
# handles unbalanced quotes by treating them as part of the # handles unbalanced quotes by treating them as part of the
# argument they were found within. # argument they were found within.
sub split_line ($line, %opts) { sub split_line($line, %opts) {
my %default_opts = ( my %default_opts = (
strip_quotes => 0, strip_quotes => 0,
keep_spaces => 0, keep_spaces => 0,
preserve_escapes => 1, preserve_escapes => 0,
strip_commas => 0,
); );
print STDERR "split: [$line]\n";
%opts = (%default_opts, %opts); %opts = (%default_opts, %opts);
return () if not length $line;
my @chars = split //, $line; my @chars = split //, $line;
my @args; my @args;
my $escaped = 0; my $ch;
my $pos;
my $quote; my $quote;
my $token = ''; my $escaped = 0;
my $last_token = ''; my $token = '';
my $ch = ' '; my $last_token = '';
my $i = 0; my $i = 0;
my $pos = 0;
my $ignore_quote = 0; my $ignore_quote = 0;
my $spaces = 0; my $spaces = 0;
my $add_token = 0;
my $got_ch = 0;
while (1) { while (1) {
if ($i >= @chars) { if ($i >= @chars) {
if (defined $quote) { if (defined $quote) {
# reached end, but unbalanced quote... reset to beginning of quote and ignore it # reached end, but unbalanced quote... reset to beginning of quote and ignore it
$i = $pos; $i = $pos;
$ignore_quote = 1; $ignore_quote = 1;
$quote = undef; $quote = undef;
$token = $last_token; $token = $last_token;
} else { } else {
# add final token and exit # add final token and exit
push @args, $token if length $token; $token .= '\\' if $escaped;
push @args, $token;
last; last;
} }
} }
$ch = $chars[$i++]; $ch = $chars[$i++];
my $dquote = $quote // 'undef';
$spaces = 0 if $ch ne ' '; $spaces = 0 if $ch ne ' ';
if ($escaped) { if ($escaped) {
if ($add_token) {
push @args, $token;
$token = '';
$add_token = 0;
}
if ($opts{preserve_escapes}) { if ($opts{preserve_escapes}) {
$token .= "\\$ch"; $token .= "\\$ch";
} else { } else {
$token .= $ch; $token .= $ch;
} }
$escaped = 0; $escaped = 0;
next; next;
} }
if ($ch eq '\\') { if ($ch eq '\\') {
$escaped = 1; $escaped = 1;
$got_ch = 1;
next; next;
} }
@ -86,34 +101,56 @@ sub split_line ($line, %opts) {
} }
if (not defined $quote and ($ch eq "'" or $ch eq '"')) { if (not defined $quote and ($ch eq "'" or $ch eq '"')) {
$got_ch = 1;
if ($add_token) {
push @args, $token;
$token = '';
$add_token = 0;
}
if ($ignore_quote) { if ($ignore_quote) {
# treat unbalanced quote as part of this argument # treat unbalanced quote as part of this argument
$token .= $ch; $token .= $ch;
$ignore_quote = 0; $ignore_quote = 0;
} else { } else {
# begin potential quoted argument # begin potential quoted argument
$pos = $i - 1; $pos = $i - 1;
$quote = $ch; $quote = $ch;
$last_token = $token; $last_token = $token;
$token .= $ch unless $opts{strip_quotes}; $token .= $ch unless $opts{strip_quotes};
} }
next; next;
} }
if ($ch eq ' ') { if ($ch eq ' ' or $ch eq "\n" or $ch eq "\t" or ($opts{strip_commas} and $ch eq ',')) {
if (++$spaces > 1 and $opts{keep_spaces}) { if (++$spaces > 1 and $opts{keep_spaces}) {
$token .= $ch; $token .= $ch;
next; next;
} else { } else {
push @args, $token if length $token; if ($opts{keep_spaces} && $ch eq "\n") {
$token = ''; $token .= $ch;
}
unless ($opts{strip_commas} and $token eq ',') {
$add_token = 1 if $got_ch;;
}
next; next;
} }
} }
if ($add_token) {
push @args, $token;
$token = '';
$add_token = 0;
}
$got_ch = 1;
$token .= $ch; $token .= $ch;
} }
use Data::Dumper;
print STDERR "split: ", Dumper(\@args), "\n";
return @args; return @args;
} }

View File

@ -16,39 +16,47 @@ our @EXPORT = qw(split_line);
# splits line into arguments separated by unquoted whitespace. # splits line into arguments separated by unquoted whitespace.
# handles unbalanced quotes by treating them as part of the # handles unbalanced quotes by treating them as part of the
# argument they were found within. # argument they were found within.
sub split_line ($line, %opts) { sub split_line($line, %opts) {
my %default_opts = ( my %default_opts = (
strip_quotes => 0, strip_quotes => 0,
keep_spaces => 0, keep_spaces => 0,
preserve_escapes => 1, preserve_escapes => 0,
strip_commas => 0,
); );
print STDERR "split: [$line]\n";
%opts = (%default_opts, %opts); %opts = (%default_opts, %opts);
return () if not length $line;
my @chars = split //, $line; my @chars = split //, $line;
my @args; my @args;
my $escaped = 0; my $ch;
my $pos;
my $quote; my $quote;
my $token = ''; my $escaped = 0;
my $last_token = ''; my $token = '';
my $ch = ' '; my $last_token = '';
my $i = 0; my $i = 0;
my $pos = 0;
my $ignore_quote = 0; my $ignore_quote = 0;
my $spaces = 0; my $spaces = 0;
my $add_token = 0;
my $got_ch = 0;
while (1) { while (1) {
if ($i >= @chars) { if ($i >= @chars) {
if (defined $quote) { if (defined $quote) {
# reached end, but unbalanced quote... reset to beginning of quote and ignore it # reached end, but unbalanced quote... reset to beginning of quote and ignore it
$i = $pos; $i = $pos;
$ignore_quote = 1; $ignore_quote = 1;
$quote = undef; $quote = undef;
$token = $last_token; $token = $last_token;
} else { } else {
# add final token and exit # add final token and exit
push @args, $token if length $token; $token .= '\\' if $escaped;
push @args, $token;
last; last;
} }
} }
@ -58,17 +66,25 @@ sub split_line ($line, %opts) {
$spaces = 0 if $ch ne ' '; $spaces = 0 if $ch ne ' ';
if ($escaped) { if ($escaped) {
if ($add_token) {
push @args, $token;
$token = '';
$add_token = 0;
}
if ($opts{preserve_escapes}) { if ($opts{preserve_escapes}) {
$token .= "\\$ch"; $token .= "\\$ch";
} else { } else {
$token .= $ch; $token .= $ch;
} }
$escaped = 0; $escaped = 0;
next; next;
} }
if ($ch eq '\\') { if ($ch eq '\\') {
$escaped = 1; $escaped = 1;
$got_ch = 1;
next; next;
} }
@ -85,34 +101,56 @@ sub split_line ($line, %opts) {
} }
if (not defined $quote and ($ch eq "'" or $ch eq '"')) { if (not defined $quote and ($ch eq "'" or $ch eq '"')) {
$got_ch = 1;
if ($add_token) {
push @args, $token;
$token = '';
$add_token = 0;
}
if ($ignore_quote) { if ($ignore_quote) {
# treat unbalanced quote as part of this argument # treat unbalanced quote as part of this argument
$token .= $ch; $token .= $ch;
$ignore_quote = 0; $ignore_quote = 0;
} else { } else {
# begin potential quoted argument # begin potential quoted argument
$pos = $i - 1; $pos = $i - 1;
$quote = $ch; $quote = $ch;
$last_token = $token; $last_token = $token;
$token .= $ch unless $opts{strip_quotes}; $token .= $ch unless $opts{strip_quotes};
} }
next; next;
} }
if ($ch eq ' ') { if ($ch eq ' ' or $ch eq "\n" or $ch eq "\t" or ($opts{strip_commas} and $ch eq ',')) {
if ($opts{keep_spaces} && (++$spaces > 1 || $ch eq "\n")) { if (++$spaces > 1 and $opts{keep_spaces}) {
$token .= $ch; $token .= $ch;
next; next;
} else { } else {
push @args, $token if length $token; if ($opts{keep_spaces} && $ch eq "\n") {
$token = ''; $token .= $ch;
}
unless ($opts{strip_commas} and $token eq ',') {
$add_token = 1 if $got_ch;;
}
next; next;
} }
} }
if ($add_token) {
push @args, $token;
$token = '';
$add_token = 0;
}
$got_ch = 1;
$token .= $ch; $token .= $ch;
} }
use Data::Dumper;
print STDERR "split: ", Dumper(\@args), "\n";
return @args; return @args;
} }

View File

@ -46,6 +46,7 @@ our %factoid_metadata = (
'ref_user' => 'TEXT', 'ref_user' => 'TEXT',
'require_explicit_args' => 'INTEGER', 'require_explicit_args' => 'INTEGER',
'requires_arguments' => 'INTEGER', 'requires_arguments' => 'INTEGER',
'suppress-no-output' => 'INTEGER',
'type' => 'TEXT', 'type' => 'TEXT',
'unquote_spaces' => 'INTEGER', 'unquote_spaces' => 'INTEGER',
'usage' => 'TEXT', 'usage' => 'TEXT',

View File

@ -392,6 +392,14 @@ sub interpret($self, $context) {
} }
} }
if ($self->{pbot}->{commands}->get_meta($keyword, 'suppress-no-output')
or $self->{pbot}->{factoids}->{data}->get_meta($fact_channel, $fact_trigger, 'suppress-no-output'))
{
$context->{'suppress_no_output'} = 1;
} else {
delete $context->{'suppress_no_output'};
}
if ($self->{pbot}->{commands}->get_meta($keyword, 'dont-replace-pronouns') if ($self->{pbot}->{commands}->get_meta($keyword, 'dont-replace-pronouns')
or $self->{pbot}->{factoids}->{data}->get_meta($fact_channel, $fact_trigger, 'dont-replace-pronouns')) or $self->{pbot}->{factoids}->{data}->get_meta($fact_channel, $fact_trigger, 'dont-replace-pronouns'))
{ {
@ -1203,18 +1211,19 @@ sub split_line($self, $line, %opts) {
my @chars = split //, $line; my @chars = split //, $line;
my @args; my @args;
my $escaped = 0; my $ch;
my $quote;
my $token = '';
my $last_token = '';
my $ch = ' ';
my $i = 0;
my $pos; my $pos;
my $quote;
my $escaped = 0;
my $token = '';
my $last_token = '';
my $i = 0;
my $ignore_quote = 0; my $ignore_quote = 0;
my $spaces = 0; my $spaces = 0;
my $add_token = 0;
my $got_ch = 0;
while (1) { while (1) {
if ($i >= @chars) { if ($i >= @chars) {
if (defined $quote) { if (defined $quote) {
# reached end, but unbalanced quote... reset to beginning of quote and ignore it # reached end, but unbalanced quote... reset to beginning of quote and ignore it
@ -1225,7 +1234,7 @@ sub split_line($self, $line, %opts) {
} else { } else {
# add final token and exit # add final token and exit
$token .= '\\' if $escaped; $token .= '\\' if $escaped;
push @args, $token if length $token; push @args, $token;
last; last;
} }
} }
@ -1235,17 +1244,25 @@ sub split_line($self, $line, %opts) {
$spaces = 0 if $ch ne ' '; $spaces = 0 if $ch ne ' ';
if ($escaped) { if ($escaped) {
if ($add_token) {
push @args, $token;
$token = '';
$add_token = 0;
}
if ($opts{preserve_escapes}) { if ($opts{preserve_escapes}) {
$token .= "\\$ch"; $token .= "\\$ch";
} else { } else {
$token .= $ch; $token .= $ch;
} }
$escaped = 0; $escaped = 0;
next; next;
} }
if ($ch eq '\\') { if ($ch eq '\\') {
$escaped = 1; $escaped = 1;
$got_ch = 1;
next; next;
} }
@ -1262,6 +1279,14 @@ sub split_line($self, $line, %opts) {
} }
if (not defined $quote and ($ch eq "'" or $ch eq '"')) { if (not defined $quote and ($ch eq "'" or $ch eq '"')) {
$got_ch = 1;
if ($add_token) {
push @args, $token;
$token = '';
$add_token = 0;
}
if ($ignore_quote) { if ($ignore_quote) {
# treat unbalanced quote as part of this argument # treat unbalanced quote as part of this argument
$token .= $ch; $token .= $ch;
@ -1286,14 +1311,19 @@ sub split_line($self, $line, %opts) {
} }
unless ($opts{strip_commas} and $token eq ',') { unless ($opts{strip_commas} and $token eq ',') {
push @args, $token if length $token; $add_token = 1 if $got_ch;;
} }
$token = '';
next; next;
} }
} }
if ($add_token) {
push @args, $token;
$token = '';
$add_token = 0;
}
$got_ch = 1;
$token .= $ch; $token .= $ch;
} }
@ -1303,7 +1333,7 @@ sub split_line($self, $line, %opts) {
# creates an array of arguments from a string # creates an array of arguments from a string
sub make_args($self, $string, %opts) { sub make_args($self, $string, %opts) {
my %default_opts = ( my %default_opts = (
keep_spaces => 1, keep_spaces => 0,
preserve_escapes => 1, preserve_escapes => 1,
); );

View File

@ -153,8 +153,11 @@ sub process_pipe_reader($self, $pid, $buf) {
# check for output # check for output
if (not defined $context->{result} or not length $context->{result}) { if (not defined $context->{result} or not length $context->{result}) {
$self->{pbot}->{logger}->log("No result from process.\n"); $self->{pbot}->{logger}->log("No result from process.\n");
return if $context->{suppress_no_output}; if ($context->{suppress_no_output}) {
$context->{result} = "No output."; $context->{result} = '';
} else {
$context->{result} = "No output.";
}
} }
# don't output unnecessary result if command was embedded within a message # don't output unnecessary result if command was embedded within a message
@ -165,12 +168,6 @@ sub process_pipe_reader($self, $pid, $buf) {
# handle code factoid result # handle code factoid result
if (exists $context->{special} and $context->{special} eq 'code-factoid') { if (exists $context->{special} and $context->{special} eq 'code-factoid') {
$context->{result} =~ s/\s+$//g; $context->{result} =~ s/\s+$//g;
if (not length $context->{result}) {
$self->{pbot}->{logger}->log("No text result from code-factoid.\n");
return;
}
$context->{original_keyword} = $context->{root_keyword}; $context->{original_keyword} = $context->{root_keyword};
$context->{result} = $self->{pbot}->{factoids}->{interpreter}->handle_action($context, $context->{result}); $context->{result} = $self->{pbot}->{factoids}->{interpreter}->handle_action($context, $context->{result});
} }

View File

@ -25,7 +25,7 @@ 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 => 4830, BUILD_REVISION => 4831,
BUILD_DATE => "2024-11-03", BUILD_DATE => "2024-11-03",
}; };