make success and failreason objects carry an influences hash

The hash will be used used to record a set of pages that influenced the
result of a pagespec match.

The influences are merged together when boolean and/or are encountered
in a pagespec. That means using a non-short-circuiting OR operator. And
so I use & and | when translating pagespecs, since those bitwise operators
can be overloaded. ("and" and "or" cannot, apparently).
master
Joey Hess 2009-10-07 19:40:44 -04:00
parent d1061d0094
commit c72fda7d69
2 changed files with 28 additions and 20 deletions

View File

@ -1926,10 +1926,10 @@ sub pagespec_translate ($) {
}gx) { }gx) {
my $word=$1; my $word=$1;
if (lc $word eq 'and') { if (lc $word eq 'and') {
$code.=' &&'; $code.=' &';
} }
elsif (lc $word eq 'or') { elsif (lc $word eq 'or') {
$code.=' ||'; $code.=' |';
} }
elsif ($word eq "(" || $word eq ")" || $word eq "!") { elsif ($word eq "(" || $word eq ")" || $word eq "!") {
$code.=' '.$word; $code.=' '.$word;
@ -2015,37 +2015,41 @@ sub glob2re ($) {
package IkiWiki::FailReason; package IkiWiki::FailReason;
use overload ( use overload (
'""' => sub { ${$_[0]} }, '""' => sub { $_[0][0] },
'0+' => sub { 0 }, '0+' => sub { 0 },
'!' => sub { bless $_[0], 'IkiWiki::SuccessReason'}, '!' => sub { bless $_[0], 'IkiWiki::SuccessReason'},
'&' => sub { $_[0][1]={%{$_[0][1]}, %{$_[1][1]}}; $_[0] },
'|' => sub { $_[1][1]={%{$_[0][1]}, %{$_[1][1]}}; $_[1] },
fallback => 1,
);
our @ISA = 'IkiWiki::SuccessReason';
package IkiWiki::SuccessReason;
use overload (
'""' => sub { $_[0][0] },
'0+' => sub { 1 },
'!' => sub { bless $_[0], 'IkiWiki::FailReason'},
'&' => sub { $_[1][1]={%{$_[0][1]}, %{$_[1][1]}}; $_[1] },
'|' => sub { $_[0][1]={%{$_[0][1]}, %{$_[1][1]}}; $_[0] },
fallback => 1, fallback => 1,
); );
sub new { sub new {
my $class = shift; my $class = shift;
my $value = shift; my $value = shift;
return bless \$value, $class; return bless [$value, {@_}], $class;
}
sub influences {
return keys %{$_[0][1]};
} }
package IkiWiki::ErrorReason; package IkiWiki::ErrorReason;
our @ISA = 'IkiWiki::FailReason'; our @ISA = 'IkiWiki::FailReason';
package IkiWiki::SuccessReason;
use overload (
'""' => sub { ${$_[0]} },
'0+' => sub { 1 },
'!' => sub { bless $_[0], 'IkiWiki::FailReason'},
fallback => 1,
);
sub new {
my $class = shift;
my $value = shift;
return bless \$value, $class;
};
package IkiWiki::PageSpec; package IkiWiki::PageSpec;
sub derel ($$) { sub derel ($$) {

View File

@ -1,7 +1,7 @@
#!/usr/bin/perl #!/usr/bin/perl
use warnings; use warnings;
use strict; use strict;
use Test::More tests => 54; use Test::More tests => 56;
BEGIN { use_ok("IkiWiki"); } BEGIN { use_ok("IkiWiki"); }
@ -88,3 +88,7 @@ ok(! pagespec_match("foo", "no_such_function(foo)"), "foo");
my $ret=pagespec_match("foo", "(invalid"); my $ret=pagespec_match("foo", "(invalid");
ok(! $ret, "syntax error"); ok(! $ret, "syntax error");
ok($ret =~ /syntax error/, "error message"); ok($ret =~ /syntax error/, "error message");
my $ret=pagespec_match("foo", "bar or foo");
ok($ret, "simple match");
is($ret, "foo matches foo", "stringified return");