+}
+
+sub pagespec_match_list ($$;@) {
+ my $page=shift;
+ my $pagespec=shift;
+ my %params=@_;
+
+ # Backwards compatability with old calling convention.
+ if (ref $page) {
+ print STDERR "warning: a plugin (".caller().") is using pagespec_match_list in an obsolete way, and needs to be updated\n";
+ $params{list}=$page;
+ $page=$params{location}; # ugh!
+ }
+
+ my $sub=pagespec_translate($pagespec);
+ error "syntax error in pagespec \"$pagespec\""
+ if ! defined $sub;
+ my $sort=sortspec_translate($params{sort}, $params{reverse})
+ if defined $params{sort};
+
+ my @candidates;
+ if (exists $params{list}) {
+ @candidates=exists $params{filter}
+ ? grep { ! $params{filter}->($_) } @{$params{list}}
+ : @{$params{list}};
+ }
+ else {
+ @candidates=exists $params{filter}
+ ? grep { ! $params{filter}->($_) } keys %pagesources
+ : keys %pagesources;
+ }
+
+ # clear params, remainder is passed to pagespec
+ $depends{$page}{$pagespec} |= ($params{deptype} || $DEPEND_CONTENT);
+ my $num=$params{num};
+ delete @params{qw{num deptype reverse sort filter list}};
+
+ # when only the top matches will be returned, it's efficient to
+ # sort before matching to pagespec,
+ if (defined $num && defined $sort) {
+ @candidates=IkiWiki::SortSpec::sort_pages(
+ $sort, @candidates);
+ }
+
+ my @matches;
+ my $firstfail;
+ my $count=0;
+ my $accum=IkiWiki::SuccessReason->new();
+ foreach my $p (@candidates) {
+ my $r=$sub->($p, %params, location => $page);
+ error(sprintf(gettext("cannot match pages: %s"), $r))
+ if $r->isa("IkiWiki::ErrorReason");
+ unless ($r || $r->influences_static) {
+ $r->remove_influence($p);
+ }
+ $accum |= $r;
+ if ($r) {
+ push @matches, $p;
+ last if defined $num && ++$count == $num;
+ }
+ }