Author: philip
Date: Tue Apr 16 16:14:36 2013
New Revision: 1468487
URL: http://svn.apache.org/r1468487
Log:
Add SWIG Perl support for svn_client_log3 and svn_client_log4.
* subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h
* subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
(svn_swig_pl_thunk_log_entry_receiver): New.
* subversion/bindings/swig/include/svn_types.swg:
Add the Perl typemap for
(svn_log_entry_receiver_t receiver, void *receiver_baton).
Since we now have typemaps for Perl, Python and Ruby, consolidate
them using the callback_typemap() macro. While we're at it,
do the same for the
(svn_log_message_receiver_t receiver, void *receiver_baton)
typemaps.
* subversion/bindings/swig/svn_client.i
Drop three typemaps. The first two are obviously bogus as the
types don't match, and the third is redundant as it's also in
svn_containers.swg.
* subversion/bindings/swig/include/svn_containers.swg
Add Perl typemaps for PROPHASH and changed_paths2.
Apply them for Perl (i.e. drop the restriction on Python or Ruby).
Similar to Ruby, add a variant STRINGLIST_MAY_BE_NULL of
STRINGLIST_MAY and apply it to the apr_array_header_t* revprops
parameter of svn_client_log3 and others. All functions using
this parameter explicitly allow the value to be NULL
(meaning "retrieve all revprops").
* subversion/bindings/swig/perl/native/Core.pm
Add class magic to use Swig types _p_svn_log_changed_path2_t
and _p_svn_log_entry_t and documents their methods.
Add properly namespaced aliases for the values
of enum svn_tristate_t.
* subversion/bindings/swig/perl/native/t/3client.t
(test_log_message_receiver): New, code factored surrounding test.
Run the existing test for $client->log also for $client->log2.
Add similar tests for $client->log3 and $client->log4
especially exercise all getter methods of _p_svn_log_entry_t.
Add a test for $client->log3 with a parameter targets
that is a list of a URL and relative paths (instead of
a single URL).
Patch by: Roderich Schupp <roderich.schupp{_AT_}gmail.com>
Modified:
subversion/trunk/subversion/bindings/swig/include/svn_containers.swg
subversion/trunk/subversion/bindings/swig/include/svn_types.swg
subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h
subversion/trunk/subversion/bindings/swig/perl/native/Core.pm
subversion/trunk/subversion/bindings/swig/perl/native/t/3client.t
subversion/trunk/subversion/bindings/swig/svn_client.i
Modified: subversion/trunk/subversion/bindings/swig/include/svn_containers.swg
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/include/svn_containers.swg?rev=1468487&r1=1468486&r2=1468487&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/include/svn_containers.swg
(original)
+++ subversion/trunk/subversion/bindings/swig/include/svn_containers.swg Tue
Apr 16 16:14:36 2013
@@ -265,6 +265,20 @@
#endif
+#ifdef SWIGPERL
+%typemap(out) apr_hash_t *PROPHASH
+{
+ %append_output(svn_swig_pl_prophash_to_hash($1));
+}
+
+%typemap(out) apr_hash_t *changed_paths2
+{
+ %append_output(
+ ($1) ? svn_swig_pl_convert_hash($1, $descriptor(svn_log_changed_path2_t *))
+ : &PL_sv_undef);
+}
+#endif
+
#ifdef SWIGRUBY
%typemap(in) apr_hash_t *PROPHASH
{
@@ -291,7 +305,6 @@
}
#endif
-#if defined(SWIGPYTHON) || defined(SWIGRUBY)
%apply apr_hash_t *PROPHASH {
apr_hash_t *target_props,
apr_hash_t *source_props,
@@ -300,7 +313,6 @@
apr_hash_t *revprop_table,
apr_hash_t *revprops
};
-#endif
#ifdef SWIGRUBY
%typemap(out) apr_hash_t *CHANGED_PATH_HASH
@@ -584,6 +596,10 @@
$1 = (apr_array_header_t *) svn_swig_pl_strings_to_array($input,
_global_pool);
}
+%typemap(in) const apr_array_header_t *STRINGLIST_MAY_BE_NULL {
+ $1 = SvOK($input) ? (apr_array_header_t *) svn_swig_pl_strings_to_array(
+ $input, _global_pool) : NULL;
+}
#endif
#ifdef SWIGRUBY
%typemap(in) const apr_array_header_t *STRINGLIST {
@@ -612,7 +628,7 @@
apr_array_header_t *preserved_exts
};
-#ifdef SWIGRUBY
+#if defined(SWIGPERL) || defined(SWIGRUBY)
%apply const apr_array_header_t *STRINGLIST_MAY_BE_NULL {
apr_array_header_t *revprops
};
Modified: subversion/trunk/subversion/bindings/swig/include/svn_types.swg
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/include/svn_types.swg?rev=1468487&r1=1468486&r2=1468487&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/include/svn_types.swg (original)
+++ subversion/trunk/subversion/bindings/swig/include/svn_types.swg Tue Apr 16
16:14:36 2013
@@ -708,28 +708,10 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
svn_repos_get_logs()
*/
-#ifdef SWIGPYTHON
-%typemap(in) (svn_log_message_receiver_t receiver,
- void *receiver_baton) {
- $1 = svn_swig_py_log_receiver;
- $2 = (void *)$input;
-}
-#endif
-#ifdef SWIGPERL
-%typemap(in) (svn_log_message_receiver_t receiver,
- void *receiver_baton) {
- $1 = svn_swig_pl_thunk_log_receiver;
- $2 = (void *)$input;
-}
-#endif
-
-#ifdef SWIGRUBY
-%typemap(in) (svn_log_message_receiver_t receiver,
- void *receiver_baton) {
- $1 = svn_swig_rb_log_receiver;
- $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool);
-}
-#endif
+%callback_typemap(svn_log_message_receiver_t receiver, void *receiver_baton,
+ svn_swig_py_log_receiver,
+ svn_swig_pl_thunk_log_receiver,
+ svn_swig_rb_log_receiver)
/* -----------------------------------------------------------------------
Callback: svn_log_entry_receiver_t
@@ -738,21 +720,10 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
svn_repos_get_logs4()
*/
-#ifdef SWIGPYTHON
-%typemap(in) (svn_log_entry_receiver_t receiver,
- void *receiver_baton) {
- $1 = svn_swig_py_log_entry_receiver;
- $2 = (void *)$input;
-}
-#endif
-
-#ifdef SWIGRUBY
-%typemap(in) (svn_log_entry_receiver_t receiver, void *receiver_baton)
-{
- $1 = svn_swig_rb_log_entry_receiver;
- $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool);
-}
-#endif
+%callback_typemap(svn_log_entry_receiver_t receiver, void *receiver_baton,
+ svn_swig_py_log_entry_receiver,
+ svn_swig_pl_thunk_log_entry_receiver,
+ svn_swig_rb_log_entry_receiver)
/* -----------------------------------------------------------------------
Callback: svn_commit_callback_t
Modified:
subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c?rev=1468487&r1=1468486&r2=1468487&view=diff
==============================================================================
---
subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
(original)
+++
subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
Tue Apr 16 16:14:36 2013
@@ -911,6 +911,24 @@ svn_error_t *svn_swig_pl_thunk_log_recei
return SVN_NO_ERROR;
}
+svn_error_t *svn_swig_pl_thunk_log_entry_receiver(void *baton,
+ svn_log_entry_t *log_entry,
+ apr_pool_t *pool)
+{
+ SV *receiver = baton;
+
+ if (!SvOK(receiver))
+ return SVN_NO_ERROR;
+
+ svn_swig_pl_callback_thunk(CALL_SV,
+ receiver, NULL,
+ "SS",
+ log_entry, _SWIG_TYPE("svn_log_entry_t *"),
+ pool, POOLINFO);
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t * svn_swig_pl_thunk_client_diff_summarize_func(
const svn_client_diff_summarize_t *diff,
void *baton,
Modified:
subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h?rev=1468487&r1=1468486&r2=1468487&view=diff
==============================================================================
---
subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h
(original)
+++
subversion/trunk/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h
Tue Apr 16 16:14:36 2013
@@ -108,8 +108,8 @@ SV *svn_swig_pl_revnums_to_list(const ap
svn_opt_revision_t *svn_swig_pl_set_revision(svn_opt_revision_t *rev, SV
*source);
-/* thunked log receiver function. */
-svn_error_t * svn_swig_pl_thunk_log_receiver(void *py_receiver,
+/* thunked log_message receiver function. */
+svn_error_t * svn_swig_pl_thunk_log_receiver(void *baton,
apr_hash_t *changed_paths,
svn_revnum_t rev,
const char *author,
@@ -117,6 +117,11 @@ svn_error_t * svn_swig_pl_thunk_log_rece
const char *msg,
apr_pool_t *pool);
+/* thunked log_entry receiver function. */
+svn_error_t * svn_swig_pl_thunk_log_entry_receiver(void *baton,
+ svn_log_entry_t *log_entry,
+ apr_pool_t *pool);
+
/* thunked diff summarize callback. */
svn_error_t * svn_swig_pl_thunk_client_diff_summarize_func(
const svn_client_diff_summarize_t *diff,
Modified: subversion/trunk/subversion/bindings/swig/perl/native/Core.pm
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/perl/native/Core.pm?rev=1468487&r1=1468486&r2=1468487&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/perl/native/Core.pm (original)
+++ subversion/trunk/subversion/bindings/swig/perl/native/Core.pm Tue Apr 16
16:14:36 2013
@@ -698,6 +698,45 @@ no previous history.
=cut
+package _p_svn_log_changed_path2_t;
+use SVN::Base qw(Core svn_log_changed_path2_t_);
+
+=head2 svn_log_changed_path2_t
+
+=over 4
+
+=item $lcp-E<gt>action()
+
+'A'dd, 'D'elete, 'R'eplace, 'M'odify
+
+=item $lcp-E<gt>copyfrom_path()
+
+Source path of copy, or C<undef> if there isn't any previous revision
+history.
+
+=item $lcp-E<gt>copyfrom_rev()
+
+Source revision of copy, or C<$SVN::Core::INVALID_REVNUM> if there is
+no previous history.
+
+=item $lcp-E<gt>node_kind()
+
+The type of the node, a C<$SVN::Node> enum; may be C<$SVN::Node::unknown>.
+
+=item $lcp-E<gt>text_modified()
+
+Is the text modified, a C<SVN::Tristate> enum,
+may be C<$SVN::Tristate::unknown>.
+
+=item $lcp-E<gt>props_modified()
+
+Are properties modified, a C<SVN::Tristate> enum,
+may be C<$SVN::Tristate::unknown>.
+
+=back
+
+=cut
+
package SVN::Node;
use SVN::Base qw(Core svn_node_);
@@ -710,6 +749,20 @@ $SVN::Node::dir, $SVN::Node::unknown.
=cut
+package SVN::Tristate;
+use SVN::Base qw(Core svn_tristate_);
+
+=head2 svn_tristate_t - SVN::Tristate
+
+An enum of the following constants:
+
+$SVN::Tristate::true, $SVN::Tristate::false, $SVN::Tristate::unknown
+
+Note that these true/false values have nothing to do with Perl's concept
+of truth. In fact, each constant would evaluate to true in a boolean context.
+
+=cut
+
package SVN::Depth;
use SVN::Base qw(Core svn_depth_);
@@ -848,12 +901,48 @@ Error message from the post-commit hook,
=item $commit-E<gt>repos_root()
-Repoistory root, may be undef if unknown.
+Repository root, may be C<undef> if unknown.
=back
=cut
+package _p_svn_log_entry_t;
+use SVN::Base qw(Core svn_log_entry_t_);
+
+=head2 svn_log_entry_t
+
+=item $entry-E<gt>revision()
+
+The revision of the commit.
+
+=item $entry-E<gt>revprops()
+
+A reference to a hash of requested revision properties,
+which may be C<undef> if it would contain no revprops.
+
+=item $entry-E<gt>has_children()
+
+Whether or not this message has children.
+
+=item $entry-E<gt>changed_paths2()
+
+A reference to hash containing as keys every path committed in
+C<$entry-E<gt>revision()>; the values are C<_p_svn_log_changed_path2_t>
+objects.
+
+=item $entry-E<gt>non_inheritable()
+
+Whether C<$entry-E<gt>revision()> should be interpreted as non-inheritable
+in the same sense of C<_p_svn_merge_range_t>.
+
+=item $entry-E<gt>subtractive_merge()
+
+Whether C<$entry-E<gt>revision()> is a merged revision resulting
+from a reverse merge.
+
+=cut
+
package _p_svn_auth_cred_simple_t;
use SVN::Base qw(Core svn_auth_cred_simple_t_);
Modified: subversion/trunk/subversion/bindings/swig/perl/native/t/3client.t
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/perl/native/t/3client.t?rev=1468487&r1=1468486&r2=1468487&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/perl/native/t/3client.t (original)
+++ subversion/trunk/subversion/bindings/swig/perl/native/t/3client.t Tue Apr
16 16:14:36 2013
@@ -20,7 +20,7 @@
#
#
-use Test::More tests => 223;
+use Test::More tests => 262;
use strict;
# shut up about variables that are only used once.
@@ -346,70 +346,155 @@ isa_ok($svn_error, '_p_svn_error_t',
$svn_error->clear(); #don't leak this
# test getting the log
-# TEST
+
+sub test_log_message_receiver {
+ my ($changed_paths,$revision,
+ $author,$date,$message,$pool) = @_;
+ # TEST
+ isa_ok($changed_paths,'HASH',
+ 'changed_paths param is a HASH');
+ # TEST
+ isa_ok($changed_paths->{'/dir1/new'},
+ '_p_svn_log_changed_path_t',
+ 'Hash value is a _p_svn_log_changed_path_t');
+ # TEST
+ is($changed_paths->{'/dir1/new'}->action(),'A',
+ 'action returns A for add');
+ # TEST
+ is($changed_paths->{'/dir1/new'}->copyfrom_path(),undef,
+ 'copyfrom_path returns undef as it is not a copy');
+ # TEST
+ is($changed_paths->{'/dir1/new'}->copyfrom_rev(),
+ $SVN::Core::INVALID_REVNUM,
+ 'copyfrom_rev is set to INVALID as it is not a copy');
+ # TEST
+ is($revision,$current_rev,
+ 'revision param matches current rev');
+ # TEST
+ is($author,$username,
+ 'author param matches expected username');
+ # TEST
+ ok($date,'date param is defined');
+ # TEST
+ is($message,'Add new',
+ 'message param is the expected value');
+ # TEST
+ isa_ok($pool,'_p_apr_pool_t',
+ 'pool param is _p_apr_pool_t');
+}
+
+# TEST log range $current_rev:$current_rev
is($ctx->log("$reposurl/dir1/new",$current_rev,$current_rev,1,0,
- sub
- {
- my ($changed_paths,$revision,
- $author,$date,$message,$pool) = @_;
- # TEST
- isa_ok($changed_paths,'HASH',
- 'changed_paths param is a HASH');
- # TEST
- isa_ok($changed_paths->{'/dir1/new'},
- '_p_svn_log_changed_path_t',
- 'Hash value is a _p_svn_log_changed_path_t');
- # TEST
- is($changed_paths->{'/dir1/new'}->action(),'A',
- 'action returns A for add');
- # TEST
- is($changed_paths->{'/dir1/new'}->copyfrom_path(),undef,
- 'copyfrom_path returns undef as it is not a copy');
- # TEST
- is($changed_paths->{'/dir1/new'}->copyfrom_rev(),
- $SVN::Core::INVALID_REVNUM,
- 'copyfrom_rev is set to INVALID as it is not a copy');
- # TEST
- is($revision,$current_rev,
- 'revision param matches current rev');
- # TEST
- is($author,$username,
- 'author param matches expected username');
- # TEST
- ok($date,'date param is defined');
- # TEST
- is($message,'Add new',
- 'message param is the expected value');
- # TEST
- isa_ok($pool,'_p_apr_pool_t',
- 'pool param is _p_apr_pool_t');
- }),
+ \&test_log_message_receiver),
undef,
'log returns undef');
+# TEST log2 range $current_rev:0 limit=1
+is($ctx->log2("$reposurl/dir1/new",$current_rev,0,1,1,0,
+ \&test_log_message_receiver),
+ undef,
+ 'log2 returns undef');
+# TEST log3 range $current_rev:0 limit=1
+is($ctx->log3("$reposurl/dir1/new",'HEAD',$current_rev,0,1,1,0,
+ \&test_log_message_receiver),
+ undef,
+ 'log3 returns undef');
+
+my @new_paths = qw( dir1/new dir1/new2 dir1/new3 dir1/new4 );
+$ctx->log3([ $reposurl, @new_paths ],
+ 'HEAD',$current_rev,0,1,1,0, sub {
+ my ($changed_paths,$revision,$author,$date,$message,$pool) = @_;
+ # TEST
+ is_deeply([sort keys %$changed_paths],
+ [sort map { "/$_" } @new_paths],
+ "changed_paths for multiple targets");
+});
+
+sub get_full_log {
+ my ($rev) = @_;
+ my @log;
+ $ctx->log($reposurl, $rev, 0, 0, 0, sub {
+ my (undef, $revision, $author, $date, $msg, undef) = @_;
+ push @log, [ $revision, $author, $date, $msg ];
+ });
+ return \@log;
+}
# TEST
my $opt_revision_head = SVN::_Core::new_svn_opt_revision_t();
$opt_revision_head->kind($SVN::Core::opt_revision_head);
-is_deeply(get_log2($opt_revision_head), # got
- get_log2("HEAD")); # expected
+is_deeply(get_full_log($opt_revision_head), # got
+ get_full_log('HEAD')); # expected
# TEST
my $opt_revision_number = SVN::_Core::new_svn_opt_revision_t();
$opt_revision_number->kind($SVN::Core::opt_revision_number);
$opt_revision_number->value->number($current_rev);
-is_deeply(get_log2($opt_revision_number), # got
- get_log2($current_rev)); # expected
+is_deeply(get_full_log($opt_revision_number), # got
+ get_full_log($current_rev)); # expected
-sub get_log2 {
- my ($rev) = @_;
- my @log;
- $ctx->log2($reposurl, $rev, $rev, 0, 0, 0, sub {
- my (undef, $revision, $author, $date, $msg, undef) = @_;
- push @log, [ $revision, $author, $date, $msg ];
- });
- return \@log;
+sub test_log_entry_receiver {
+ my ($log_entry,$pool) = @_;
+ # TEST
+ isa_ok($log_entry, '_p_svn_log_entry_t',
+ 'log_entry param is a _p_svn_log_entry_t');
+ # TEST
+ isa_ok($pool,'_p_apr_pool_t',
+ 'pool param is _p_apr_pool_t');
+ # TEST
+ is($log_entry->revision,$current_rev,
+ 'log_entry->revision matches current rev');
+
+ my $revprops = $log_entry->revprops;
+ # TEST
+ isa_ok($revprops,'HASH',
+ 'log_entry->revprops is a HASH');
+ # TEST
+ is($revprops->{"svn:author"},$username,
+ 'svn:author revprop matches expected username');
+ # TEST
+ ok($revprops->{"svn:date"},'svn:date revprop is defined');
+ # TEST
+ is($revprops->{"svn:log"},'Add new',
+ 'svn:log revprop is the expected value');
+
+ my $changed_paths = $log_entry->changed_paths2;
+ # TEST
+ isa_ok($changed_paths,'HASH',
+ 'log_entry->changed_paths2 is a HASH');
+ # TEST
+ isa_ok($changed_paths->{'/dir1/new'},
+ '_p_svn_log_changed_path2_t',
+ 'Hash value is a _p_svn_log_changed_path2_t');
+ # TEST
+ is($changed_paths->{'/dir1/new'}->action(),'A',
+ 'action returns A for add');
+ # TEST
+ is($changed_paths->{'/dir1/new'}->node_kind(),$SVN::Node::file,
+ 'node_kind returns $SVN::Node::file');
+ # TEST
+ is($changed_paths->{'/dir1/new'}->text_modified(),$SVN::Tristate::true,
+ 'text_modified returns true');
+ # TEST
+ is($changed_paths->{'/dir1/new'}->props_modified(),$SVN::Tristate::false,
+ 'props_modified returns false');
+ # TEST
+ is($changed_paths->{'/dir1/new'}->copyfrom_path(),undef,
+ 'copyfrom_path returns undef as it is not a copy');
+ # TEST
+ is($changed_paths->{'/dir1/new'}->copyfrom_rev(),
+ $SVN::Core::INVALID_REVNUM,
+ 'copyfrom_rev is set to INVALID as it is not a copy');
}
# TEST
+is($ctx->log4("$reposurl/dir1/new",
+ 'HEAD',$current_rev,0,1, # peg rev, start rev, end rev, limit
+ 1,1,0, # discover_changed_paths, strict_node_history,
include_merged_revisions
+ undef, # revprops
+ \&test_log_entry_receiver),
+ undef,
+ 'log4 returns undef');
+
+# TEST
is($ctx->update($wcpath,'HEAD',1),$current_rev,
'Return from update is the current rev');
Modified: subversion/trunk/subversion/bindings/swig/svn_client.i
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/svn_client.i?rev=1468487&r1=1468486&r2=1468487&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/svn_client.i (original)
+++ subversion/trunk/subversion/bindings/swig/svn_client.i Tue Apr 16 16:14:36
2013
@@ -49,13 +49,7 @@
%apply const char *MAY_BE_NULL {
const char *native_eol,
const char *comment,
- const char *relative_to_dir,
- apr_hash_t *revprop_table,
- apr_array_header_t *changelists
-};
-
-%apply apr_hash_t *PROPHASH {
- apr_hash_t *revprop_table
+ const char *relative_to_dir
};
#ifdef SWIGRUBY