X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/86660e9c82b67f9165cb5fabe28c341a338d8c4e..9da467f063231185de7b336c36a62c08d1258ff4:/IkiWiki/Plugin/external.pm?ds=sidebyside

diff --git a/IkiWiki/Plugin/external.pm b/IkiWiki/Plugin/external.pm
index ba6c7d8b9..a4cc1dd3c 100644
--- a/IkiWiki/Plugin/external.pm
+++ b/IkiWiki/Plugin/external.pm
@@ -6,15 +6,14 @@ package IkiWiki::Plugin::external;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use RPC::XML;
-use RPC::XML::Parser;
 use IPC::Open2;
 use IO::Handle;
 
 my %plugins;
 
-sub import { #{{{
+sub import {
 	my $self=shift;
 	my $plugin=shift;
 	return unless defined $plugin;
@@ -29,20 +28,22 @@ sub import { #{{{
 
 	$plugins{$plugin}={in => $plugin_read, out => $plugin_write, pid => $pid,
 		accum => ""};
+
 	$RPC::XML::ENCODING="utf-8";
+	$RPC::XML::FORCE_STRING_ENCODING="true";
 
 	rpc_call($plugins{$plugin}, "import");
-} #}}}
+}
 
-sub rpc_write ($$) { #{{{
+sub rpc_write ($$) {
 	my $fh=shift;
 	my $string=shift;
 
 	$fh->print($string."\n");
 	$fh->flush;
-} #}}}
+}
 
-sub rpc_call ($$;@) { #{{{
+sub rpc_call ($$;@) {
 	my $plugin=shift;
 	my $command=shift;
 
@@ -55,7 +56,19 @@ sub rpc_call ($$;@) { #{{{
 		$plugin->{accum}.=$_;
 		while ($plugin->{accum} =~ /^\s*(<\?xml\s.*?<\/(?:methodCall|methodResponse)>)\n(.*)/s) {
 			$plugin->{accum}=$2;
-			my $r = RPC::XML::Parser->new->parse($1);
+			my $parser;
+			eval q{
+				use RPC::XML::ParserFactory;
+				$parser = RPC::XML::ParserFactory->new;
+			};
+			if ($@) {
+				# old interface
+				eval q{
+					use RPC::XML::Parser;
+					$parser = RPC::XML::Parser->new;
+				};
+			}
+			my $r=$parser->parse($1);
 			error("XML RPC parser failure: $r") unless ref $r;
 			if ($r->isa('RPC::XML::response')) {
 				my $value=$r->value;
@@ -72,9 +85,9 @@ sub rpc_call ($$;@) { #{{{
 
 					# XML-RPC v1 does not allow for
 					# nil/null/None/undef values to be
-					# transmitted, so until
-					# XML::RPC::Parser honours v2
-					# (<nil/>), external plugins send
+					# transmitted. The <nil/> extension
+					# is the right fix, but for
+					# back-compat, let external plugins send
 					# a hash with one key "null" pointing
 					# to an empty string.
 					if (exists $hash{null} &&
@@ -131,12 +144,12 @@ sub rpc_call ($$;@) { #{{{
 	}
 
 	return undef;
-} #}}}
+}
 
 package IkiWiki::RPC::XML;
 use Memoize;
 
-sub getvar ($$$) { #{{{
+sub getvar ($$$) {
 	my $plugin=shift;
 	my $varname="IkiWiki::".shift;
 	my $key=shift;
@@ -145,9 +158,9 @@ sub getvar ($$$) { #{{{
 	my $ret=$varname->{$key};
 	use strict 'refs';
 	return $ret;
-} #}}}
+}
 
-sub setvar ($$$;@) { #{{{
+sub setvar ($$$;@) {
 	my $plugin=shift;
 	my $varname="IkiWiki::".shift;
 	my $key=shift;
@@ -157,18 +170,18 @@ sub setvar ($$$;@) { #{{{
 	my $ret=$varname->{$key}=$value;
 	use strict 'refs';
 	return $ret;
-} #}}}
+}
 
-sub getstate ($$$$) { #{{{
+sub getstate ($$$$) {
 	my $plugin=shift;
 	my $page=shift;
 	my $id=shift;
 	my $key=shift;
 
 	return $IkiWiki::pagestate{$page}{$id}{$key};
-} #}}}
+}
 
-sub setstate ($$$$;@) { #{{{
+sub setstate ($$$$;@) {
 	my $plugin=shift;
 	my $page=shift;
 	my $id=shift;
@@ -176,22 +189,22 @@ sub setstate ($$$$;@) { #{{{
 	my $value=shift;
 
 	return $IkiWiki::pagestate{$page}{$id}{$key}=$value;
-} #}}}
+}
 
-sub getargv ($) { #{{{
+sub getargv ($) {
 	my $plugin=shift;
 
 	return \@ARGV;
-} #}}}
+}
 
-sub setargv ($@) { #{{{
+sub setargv ($@) {
 	my $plugin=shift;
 	my $array=shift;
 
 	@ARGV=@$array;
-} #}}}
+}
 
-sub inject ($@) { #{{{
+sub inject ($@) {
 	# Bind a given perl function name to a particular RPC request.
 	my $plugin=shift;
 	my %params=@_;
@@ -202,12 +215,20 @@ sub inject ($@) { #{{{
 	my $sub = sub {
 		IkiWiki::Plugin::external::rpc_call($plugin, $params{call}, @_)
 	};
+	$sub=memoize($sub) if $params{memoize};
+
+	# This will add it to the symbol table even if not present.
+	no warnings;
 	eval qq{*$params{name}=\$sub};
-	memoize($params{name}) if $params{memoize};
+	use warnings;
+
+	# This will ensure that everywhere it was exported to sees
+	# the injected version.
+	IkiWiki::inject(name => $params{name}, call => $sub);
 	return 1;
-} #}}}
+}
 
-sub hook ($@) { #{{{
+sub hook ($@) {
 	# the call parameter is a function name to call, since XML RPC
 	# cannot pass a function reference
 	my $plugin=shift;
@@ -219,13 +240,16 @@ sub hook ($@) { #{{{
 	IkiWiki::hook(%params, call => sub {
 		IkiWiki::Plugin::external::rpc_call($plugin, $callback, @_);
 	});
-} #}}}
+}
 
-sub pagespec_match ($@) { #{{{
-	# convert pagespec_match's return object into a XML RPC boolean
+sub pagespec_match ($@) {
+	# convert return object into a XML RPC boolean
 	my $plugin=shift;
+	my $page=shift;
+	my $spec=shift;
 
-	return RPC::XML::boolean->new(0 + IkiWiki::pagespec_march(@_));
-} #}}}
+	return RPC::XML::boolean->new(0 + IkiWiki::pagespec_match(
+			$page, $spec, @_));
+}
 
 1