[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

svn_client_list, Perl, swig bindings

From: Nik Clayton <nik_at_ngo.org.uk>
Date: 2007-02-26 22:10:13 CET

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

This is an archived mail posted to the Subversion Dev mailing list.