Index: subversion/bindings/swig/svn_ra.i =================================================================== --- subversion/bindings/swig/svn_ra.i (revision 20227) +++ subversion/bindings/swig/svn_ra.i (working copy) @@ -174,6 +174,14 @@ } #endif +#ifdef SWIGPYTHON +%typemap(in) (const svn_ra_reporter2_t *reporter, void *report_baton) +{ + $1 = &swig_py_ra_reporter2; + $2 = (void *)$input; +} +#endif + /* ----------------------------------------------------------------------- */ %{ Index: subversion/bindings/swig/python/tests/wc.py =================================================================== --- subversion/bindings/swig/python/tests/wc.py (revision 20227) +++ subversion/bindings/swig/python/tests/wc.py (working copy) @@ -31,7 +31,7 @@ client.checkout2(self.repos_url, self.path, rev, rev, True, True, client_ctx) - self.wc = wc.adm_open3(None, self.path, True, 0, None) + self.wc = wc.adm_open3(None, self.path, True, -1, None) def test_entry(self): wc_entry = wc.entry(self.path, self.wc, True) @@ -70,6 +70,39 @@ def test_init_traversal_info(self): wc.init_traversal_info() + def test_crawl_revisions2(self): + def notify(info, pool): + pass + + class MyReporter: + def __init__(self): + self.set_paths = [] + self.finished_report = False + + def abort_report(self, pool): + pass + + def finish_report(self, pool): + self.finished_report = True + + def set_path(self, path, revision, start_empty, lock_token, pool): + self.set_paths.append(path) + + def link_path(self, path, url, revision, start_empty, lock_token, pool): + pass + + def delete_path(self, path, pool): + pass + + reporter = MyReporter() + + info = wc.init_traversal_info() + wc.crawl_revisions2(self.path, self.wc, reporter, + False, True, False, notify, info) + + self.assert_(reporter.finished_report) + self.assertEqual([''], reporter.set_paths) + def test_create_notify(self): wc.create_notify(self.path, wc.notify_add) Index: subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c =================================================================== --- subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (revision 20227) +++ subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (working copy) @@ -658,6 +658,7 @@ svn_auth_ssl_server_cert_info_dup) DECLARE_SWIG_CONSTRUCTOR(info, svn_info_dup) DECLARE_SWIG_CONSTRUCTOR(commit_info, svn_commit_info_dup) +DECLARE_SWIG_CONSTRUCTOR(wc_notify, svn_wc_dup_notify) static PyObject *convert_log_changed_path(void *value, void *ctx, PyObject *py_pool) @@ -1628,6 +1629,41 @@ } +void svn_swig_py_notify_func2(void *baton, + const svn_wc_notify_t *notify, + apr_pool_t *pool) +{ + PyObject *function = baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if (function == NULL || function == Py_None) + return; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(function, + (char *)"(O&O&)", + make_ob_wc_notify, notify, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + /* The callback shouldn't be returning anything. */ + if (result != Py_None) + err = callback_bad_return_error("Not None"); + Py_DECREF(result); + } + + /* Our error has no place to go. :-( */ + if (err) + svn_error_clear(err); + + svn_swig_py_release_py_lock(); +} + void svn_swig_py_status_func(void *baton, const char *path, svn_wc_status_t *status) @@ -2379,5 +2415,177 @@ return err; } +static svn_error_t *reporter_set_path(void *report_baton, + const char *path, + svn_revnum_t revision, + svn_boolean_t start_empty, + const char *lock_token, + apr_pool_t *pool) +{ + svn_error_t *err = SVN_NO_ERROR; + PyObject *py_reporter = report_baton, *result; + if (py_reporter == NULL || py_reporter == Py_None) + return SVN_NO_ERROR; + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallMethod(py_reporter, + (char *)"set_path", + (char *)"slbsO&", + path, revision, + start_empty, lock_token, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else if (result != Py_None) + { + err = callback_bad_return_error("Not None"); + } + + Py_XDECREF(result); + + svn_swig_py_release_py_lock(); + + return err; +} + +static svn_error_t *reporter_delete_path(void *report_baton, + const char *path, + apr_pool_t *pool) +{ + svn_error_t *err = SVN_NO_ERROR; + PyObject *py_reporter = report_baton, *result; + + if (py_reporter == NULL || py_reporter == Py_None) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallMethod(py_reporter, + (char *)"delete_path", + (char *)"sO&", + path, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else if (result != Py_None) + { + err = callback_bad_return_error("Not None"); + } + + Py_XDECREF(result); + + svn_swig_py_release_py_lock(); + + return err; +} + +static svn_error_t *reporter_link_path(void *report_baton, + const char *path, + const char *url, + svn_revnum_t revision, + svn_boolean_t start_empty, + const char *lock_token, + apr_pool_t *pool) +{ + svn_error_t *err = SVN_NO_ERROR; + PyObject *py_reporter = report_baton, *result; + + if (py_reporter == NULL || py_reporter == Py_None) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallMethod(py_reporter, + (char *)"link_path", + (char *)"sslbsO&", + path, url, revision, + start_empty, lock_token, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else if (result != Py_None) + { + err = callback_bad_return_error("Not None"); + } + + Py_XDECREF(result); + + svn_swig_py_release_py_lock(); + + return err; +} + +static svn_error_t *reporter_finish_report(void *report_baton, + apr_pool_t *pool) +{ + svn_error_t *err = SVN_NO_ERROR; + + PyObject *py_reporter = report_baton, *result; + + if (py_reporter == NULL || py_reporter == Py_None) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallMethod(py_reporter, + (char *)"finish_report", + (char *)"O&", + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else if (result != Py_None) + { + err = callback_bad_return_error("Not None"); + } + + Py_XDECREF(result); + + svn_swig_py_release_py_lock(); + + return err; +} + +static svn_error_t *reporter_abort_report(void *report_baton, + apr_pool_t *pool) +{ + svn_error_t *err = SVN_NO_ERROR; + + PyObject *py_reporter = report_baton, *result; + + if (py_reporter == NULL || py_reporter == Py_None) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallMethod(py_reporter, + (char *)"abort_report", + (char *)"O&", + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else if (result != Py_None) + { + err = callback_bad_return_error("Not None"); + } + + Py_XDECREF(result); + + svn_swig_py_release_py_lock(); + + return err; +} + +const svn_ra_reporter2_t swig_py_ra_reporter2 = { + reporter_set_path, + reporter_delete_path, + reporter_link_path, + reporter_finish_report, + reporter_abort_report +}; Index: subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h =================================================================== --- subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h (revision 20227) +++ subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h (working copy) @@ -201,6 +201,11 @@ svn_wc_notify_state_t prop_state, svn_revnum_t revision); +SVN_SWIG_SWIGUTIL_EXPORT +void svn_swig_py_notify_func2(void *baton, + const svn_wc_notify_t *notify, + apr_pool_t *pool); + /* a status function that executes a Python function that is passed in via the baton argument */ SVN_SWIG_SWIGUTIL_EXPORT @@ -335,6 +340,9 @@ apr_array_header_t *prop_diffs, apr_pool_t *pool); +SVN_SWIG_SWIGUTIL_EXPORT +extern const svn_ra_reporter2_t swig_py_ra_reporter2; + #ifdef __cplusplus } #endif /* __cplusplus */ Index: subversion/bindings/swig/svn_wc.i =================================================================== --- subversion/bindings/swig/svn_wc.i (revision 20227) +++ subversion/bindings/swig/svn_wc.i (working copy) @@ -253,6 +253,11 @@ $1 = svn_swig_py_notify_func; $2 = $input; /* our function is the baton. */ } + +%typemap(in) (svn_wc_notify_func2_t notify_func, void *notify_baton) { + $1 = svn_swig_py_notify_func2; + $2 = $input; /* our function is the baton. */ +} #endif /* -----------------------------------------------------------------------