All,
I'm trying to wrap svn_client_list() using the SWIG bindings, to make it
accessible to Perl.
Attached is a diff that's my first cut at doing that. Since
svn_client_list() takes a parameter that (in Perl) is a subroutine
reference, I've modeled the approach on the svn_client_list()
implementation, which does the same thing.
But it doesn't work. My tests have involved:
a. Checking out the perl-bindings-improvements branch (with the patch)
b. Building the code
c. Trying to run the attached list.t in subversion/bindings/swig/perl/native as
% perl -Iblib/lib list.t
ok 1 - use Test::SVN;
ok 2 - use SVN::Client;
ok 3 - The object isa SVN::Client
Usage:
svn_client_list(path_or_url,peg_revision,revision,recurse,
dirent_fields,fetch_locks,list_func,baton,ctx,pool);1..3
# Looks like your test died just after 3.
(lines wrapped). I've about hit the extent of my swig-fu at this point.
Anyone spot my glaringly obvious mistake?
N
=== subversion/bindings/swig/include/svn_types.swg
==================================================================
--- subversion/bindings/swig/include/svn_types.swg (revision 23492)
+++ subversion/bindings/swig/include/svn_types.swg (local)
@@ -598,6 +598,19 @@
#endif
/* -----------------------------------------------------------------------
+ Callback: svn_client_list_func_t
+ svn_client_list()
+*/
+
+#ifdef SWIGPERL
+%typemap(in) (svn_client_list_func_t list_func,
+ void *baton) {
+ $1 = svn_swig_pl_thunk_list_receiver;
+ $2 = (void *)$input;
+}
+#endif
+
+/* -----------------------------------------------------------------------
Callback: svn_log_message_receiver_t
svn_client_log()
svn_ra get_log()
=== subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
==================================================================
--- subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c (revision 23492)
+++ subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c (local)
@@ -777,6 +777,30 @@
svn_swig_pl_hold_ref_in_pool(pool, perl_editor);
}
+svn_error_t *svn_swig_pl_thunk_list_receiver(void *baton,
+ const char *path,
+ const svn_dirent_t *dirent,
+ const svn_lock_t *lock,
+ const char *abs_path,
+ apr_pool_t *pool)
+{
+ SV *receiver = baton;
+ swig_type_info *dirent_type = _SWIG_TYPE("svn_dirent_t *");
+ swig_type_info *lock_type = _SWIG_TYPE("svn_lock_t *");
+
+ if (!SvOK(receiver))
+ return SVN_NO_ERROR;
+
+ svn_swig_pl_callback_thunk(CALL_SV,
+ receiver, NULL,
+ "sOOsS", path,
+ svn_swig_pl_convert_hash(dirent, dirent_type),
+ svn_swig_pl_convert_hash(lock, lock_type),
+ abs_path, pool);
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *svn_swig_pl_thunk_log_receiver(void *baton,
apr_hash_t *changed_paths,
svn_revnum_t rev,
=== subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h
==================================================================
--- subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h (revision 23492)
+++ subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h (local)
@@ -95,6 +95,14 @@
SV *svn_swig_pl_convert_array(const apr_array_header_t *array,
swig_type_info *tinfo);
+/* thunked list receiver function. */
+svn_error_t *svn_swig_pl_thunk_list_receiver(void *baton,
+ const char *path,
+ const svn_dirent_t *dirent,
+ const svn_lock_t *lock,
+ const char *abs_path,
+ apr_pool_t *pool);
+
/* thunked log receiver function. */
svn_error_t * svn_swig_pl_thunk_log_receiver(void *py_receiver,
apr_hash_t *changed_paths,
#!/usr/bin/perl
use strict;
use warnings;
use Test::More qw(no_plan); #tests => 79;
use lib 't/lib';
BEGIN {
use_ok('Test::SVN', qw(create_and_load_repo));
use_ok('SVN::Client');
}
my $repo_path = create_and_load_repo('t/repo.dump');
my $repo_url = "file://$repo_path";
my $ctx = SVN::Client->new();
isa_ok($ctx, 'SVN::Client');
use Data::Dumper;
#diag Dumper $ctx->list({
# path_or_url => $repo_url,
# peg_revision => 1,
# revision => 1,
# recurse => 0,
# dirent_fields => 0xffffffff, # SVN_DIRENT_ALL
# fetch_locks => 1,
# list_func => sub { diag Dumper \@_; },
#});
diag Dumper $ctx->list($repo_url, 1, 1, 0, 2, 1, sub { diag Dumper \@_; });
ok(1);
__END__
my $dirents;
diag 'Testing r0';
foreach my $args (([$repo_url, 0, 1],
[ { path_or_url => $repo_url, revision => 0, recurse => 1 } ])) {
$dirents = $ctx->ls(@{ $args });
isa_ok($dirents, 'HASH');
is_deeply($dirents, { }, 'r0 is empty');
}
diag 'Testing r1';
foreach my $args (([$repo_url, 1, 1],
[ { path_or_url => $repo_url, revision => 1, recurse => 1 } ])) {
$dirents = $ctx->ls(@{ $args });
is(scalar keys %{ $dirents }, 20, '20 dirents listed');
foreach my $dirent (keys %{ $dirents }) {
isa_ok($dirents->{$dirent}, '_p_svn_dirent_t');
}
is($dirents->{'A'}->size(), 0, '/A size is zero');
is($dirents->{'A'}->kind(), $SVN::Node::dir, '/A is a directory');
is($dirents->{'A'}->has_props(), 0, '/A has no properties');
my $iota = $dirents->{'iota'};
is($iota->kind(), $SVN::Node::file, '/iota is a file');
is($iota->size(), 25, '/iota is 25 bytes');
is($iota->has_props(), 0, '/iota has no properties');
is($iota->created_rev(), 1, '/iota was changed in this rev');
is($iota->time, 1171532569978151, '/iota has correct change time');
is($iota->last_author(), 'nik', '/iota has correct author');
}
foreach my $args ((["$repo_url/A", 1, 0],
[ { path_or_url => "$repo_url/A", revision => 1, recurse => 0 } ],
[ { path_or_url => "$repo_url/A", revision => 1 } ], )) {
$dirents = $ctx->ls(@{ $args });
foreach my $dirent (qw(B C D)) {
is($dirents->{$dirent}->kind(), $SVN::Node::dir, "/A/$dirent is a directory");
}
is($dirents->{'mu'}->kind(), $SVN::Node::file, '/A/mu is a file');
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Feb 26 22:11:01 2007