diff -Nur subversion-1.3.1/build.conf subversion-1.3.1.new/build.conf --- subversion-1.3.1/build.conf 2006-07-05 01:03:58.000000000 +0100 +++ subversion-1.3.1.new/build.conf 2006-07-05 01:04:06.000000000 +0100 @@ -351,7 +351,7 @@ type = swig_lib lang = python path = subversion/bindings/swig/python/libsvn_swig_py -libs = libsvn_subr libsvn_delta libsvn_wc apr +libs = libsvn_client libsvn_subr libsvn_delta libsvn_wc apr link-cmd = $(LINK) $(SWIG_PY_LIBS) install = swig-py-lib # need special build rule to include -DSWIGPYTHON diff -Nur subversion-1.3.1/subversion/bindings/swig/include/apr.swg subversion-1.3.1.new/subversion/bindings/swig/include/apr.swg --- subversion-1.3.1/subversion/bindings/swig/include/apr.swg 2005-10-25 20:16:38.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/include/apr.swg 2006-07-05 01:04:06.000000000 +0100 @@ -146,14 +146,24 @@ /* ----------------------------------------------------------------------- create an OUTPUT argument defn for an apr_hash_t ** which is storing + dirent values +*/ +%typemap(python,in,numinputs=0) apr_hash_t **DIRENTHASH = apr_hash_t **OUTPUT; +%typemap(python,argout,fragment="t_output_helper") apr_hash_t **DIRENTHASH { + $result = t_output_helper($result, + svn_swig_py_convert_hash(*$1, + SWIGTYPE_p_svn_dirent_t, + NULL)); +} + +/* ----------------------------------------------------------------------- + create an OUTPUT argument defn for an apr_hash_t ** which is storing property values */ %typemap(python,in,numinputs=0) apr_hash_t **PROPHASH = apr_hash_t **OUTPUT; -%typemap(python,argout) apr_hash_t **PROPHASH { - /* toss prior result, get new result from the hash */ - Py_DECREF($result); - $result = svn_swig_py_prophash_to_dict(*$1); +%typemap(python,argout,fragment="t_output_helper") apr_hash_t **PROPHASH { + $result = t_output_helper($result, svn_swig_py_prophash_to_dict(*$1)); } %typemap(perl5,in,numinputs=0) apr_hash_t **PROPHASH = apr_hash_t **OUTPUT; diff -Nur subversion-1.3.1/subversion/bindings/swig/include/proxy_apr.swg subversion-1.3.1.new/subversion/bindings/swig/include/proxy_apr.swg --- subversion-1.3.1/subversion/bindings/swig/include/proxy_apr.swg 2006-03-13 09:51:40.000000000 +0000 +++ subversion-1.3.1.new/subversion/bindings/swig/include/proxy_apr.swg 2006-07-05 01:04:06.000000000 +0100 @@ -112,6 +112,28 @@ del self._parent_pool if hasattr(self, "_is_valid"): del self._is_valid + + # Clear out any pool-owned references inserted by typemaps + if hasattr(self, "_owned_refs"): + del self._owned_refs + + def _add_owned_ref(self, ref): + """Add a new 'owned' reference -- i.e. a Python object contained in a C + structure allocated in this pool. Used by the typemaps to manage + reference counting semantics.""" + if not hasattr(self, "_owned_refs"): + self._owned_refs = {} + if self._owned_refs.has_key(ref): + self._owned_refs[ref] += 1 + else: + self._owned_refs[ref] = 1 + + def _remove_owned_ref(self, ref): + """Remove an existing 'owned' reference. Also used by typemaps.""" + if hasattr(self, "_owned_refs") and self._owned_refs.has_key(ref): + self._owned_refs[ref] -= 1 + if self._owned_refs[ref] == 0: + del self._owned_refs[ref] def __del__(self): """Automatically destroy memory pools, if necessary""" diff -Nur subversion-1.3.1/subversion/bindings/swig/include/proxy_apr.swg.orig subversion-1.3.1.new/subversion/bindings/swig/include/proxy_apr.swg.orig --- subversion-1.3.1/subversion/bindings/swig/include/proxy_apr.swg.orig 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/include/proxy_apr.swg.orig 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,185 @@ +/* Proxy classes for apr_*. Generated by hand. */ + +#ifdef SWIGPYTHON +%include proxy.swg + +%nodefault apr_array_header_t; +%nodefault apr_file_t; +%nodefault apr_hash_t; +%nodefault apr_pool_t; + +%opaque_proxy(apr_array_header_t); +%opaque_proxy(apr_file_t); +%opaque_proxy(apr_hash_t); + +%pythoncode %{ +import threading + +application_pool = None +application_pool_lock = threading.Lock() +class GenericSWIGWrapper: + def __init__(self, this, pool): + """Create new Generic SWIG wrapper object""" + import weakref + self.this = this + self._parent_pool = pool + self._is_valid = weakref.ref(pool._is_valid) + + def set_parent_pool(self, pool): + """Set the parent pool of this object""" + self._parent_pool = pool + + def valid(self): + """Is this object valid?""" + return self._is_valid() + + def assert_valid(self): + """Assert that this object is still valid""" + assert self.valid(), "This object has already been destroyed" + + def _unwrap(self): + """Return underlying SWIG object""" + self.assert_valid() + return self.this + +def _mark_weakpool_invalid(weakpool): + if weakpool and weakpool() and hasattr(weakpool(), "_is_valid"): + del weakpool()._is_valid + +%} + +struct apr_pool_t { + %extend { + %pythoncode %{ + def set_parent_pool(self, parent_pool=None): + """Create a new memory pool""" + global application_pool + + try: + application_pool_lock.acquire() + + self._parent_pool = parent_pool or application_pool + self._mark_valid() + + # Protect important functions from GC + self._apr_pool_destroy = _core.apr_pool_destroy + self._svn_swig_py_clear_application_pool = \ + _core.svn_swig_py_clear_application_pool + + # If we are an application-level pool, + # then set this pool to be the application-level pool + if not self._parent_pool: + svn_swig_py_set_application_pool(self, self) + application_pool = self + finally: + application_pool_lock.release() + + def valid(self): + """Check whether this memory pool and its parents + are still valid""" + return hasattr(self,"_is_valid") + + def assert_valid(self): + """Assert that this memory_pool is still valid.""" + assert self.valid(), "This pool has already been destroyed" + + def clear(self): + """Clear embedded memory pool. Invalidate all subpools.""" + pool = self._parent_pool + apr_pool_clear(self) + self.set_parent_pool(pool) + + def destroy(self): + """Destroy embedded memory pool. If you do not destroy + the memory pool manually, Python will destroy it + automatically.""" + global application_pool + + self.assert_valid() + + is_application_pool = not self._parent_pool + + # Destroy pool + self._apr_pool_destroy(self) + + # Clear application pool if necessary + if is_application_pool: + application_pool = None + self._svn_swig_py_clear_application_pool() + + # Mark self as invalid + if hasattr(self, "_parent_pool"): + del self._parent_pool + if hasattr(self, "_is_valid"): + del self._is_valid + + # Clear out any pool-owned references inserted by typemaps + if hasattr(self, "_owned_refs"): + del self._owned_refs + + def _add_owned_ref(self, ref): + """Add a new 'owned' reference -- i.e. a Python object contained in a C + structure allocated in this pool. Used by the typemaps to manage + reference counting semantics.""" + if not hasattr(self, "_owned_refs"): + self._owned_refs = {} + if self._owned_refs.has_key(ref): + self._owned_refs[ref] += 1 + else: + self._owned_refs[ref] = 1 + + def _remove_owned_ref(self, ref): + """Remove an existing 'owned' reference. Also used by typemaps.""" + if hasattr(self, "_owned_refs") and self._owned_refs.has_key(ref): + self._owned_refs[ref] -= 1 + if self._owned_refs[ref] == 0: + del self._owned_refs[ref] + + def __del__(self): + """Automatically destroy memory pools, if necessary""" + if self.valid(): + self.destroy() + + def _mark_valid(self): + """Mark pool as valid""" + + self._weakparent = None + + if self._parent_pool: + import weakref + + # Make sure that the parent object is valid + self._parent_pool.assert_valid() + + # Refer to self using a weakrefrence so that we don't + # create a reference cycle + weakself = weakref.ref(self) + + # Set up callbacks to mark pool as invalid when parents + # are destroyed + self._weakparent = weakref.ref(self._parent_pool._is_valid, + lambda x: _mark_weakpool_invalid(weakself)) + + # Mark pool as valid + self._is_valid = lambda: 1 + + def _wrap(self, obj): + """Mark a SWIG object as owned by this pool""" + self.assert_valid() + if hasattr(obj, "set_parent_pool"): + obj.set_parent_pool(self) + return obj + elif obj is None: + return None + else: + return GenericSWIGWrapper(obj, self) + + %} + } +}; +%pythoncode %{ +# Initialize a global pool +svn_pool_create() +%} +#endif + diff -Nur subversion-1.3.1/subversion/bindings/swig/include/svn_types.swg subversion-1.3.1.new/subversion/bindings/swig/include/svn_types.swg --- subversion-1.3.1/subversion/bindings/swig/include/svn_types.swg 2005-10-25 20:03:21.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/include/svn_types.swg 2006-07-05 01:04:06.000000000 +0100 @@ -430,6 +430,12 @@ $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); }; +%typemap(python, in) (svn_commit_callback2_t callback, void *callback_baton) +{ + $1 = svn_swig_py_commit_callback2; + $2 = (void *)$input; +} + /* ----------------------------------------------------------------------- Callback: svn_cancel_func_t */ @@ -493,6 +499,60 @@ $1 = svn_swig_rb_make_stream($input); } +#ifdef SWIGPYTHON +%typemap(in) (svn_commit_callback_t callback, void *callback_baton) +{ + $1 = svn_swig_py_commit_callback; + $2 = (void *)$input; +} +#endif + +#ifdef SWIGPYTHON +%typemap(in) (svn_commit_callback_t callback, void *callback_baton) +{ + $1 = svn_swig_py_commit_callback; + $2 = (void *)$input; +} +#endif + +/* ----------------------------------------------------------------------- + Mapper to automatically turn Python objects into void* batons on assignment +*/ + +#ifdef SWIGPYTHON +%typemap(in) void *PY_AS_VOID (PyObject *newRef) { + newRef = $input; + if ($input == Py_None) { + $1 = newRef = NULL; + } else { + newRef = $input; + $1 = (void *)$input; + } + if (svn_swig_py_pool_set_owned_ref(obj0, (PyObject *)arg1->$1_name, newRef)) { + SWIG_fail; + } +} +#endif + +/* ----------------------------------------------------------------------- + Mapper to automatically turn Python objects into void* batons on assignment +*/ + +#ifdef SWIGPYTHON +%typemap(in) void *PY_AS_VOID (PyObject *newRef) { + newRef = $input; + if ($input == Py_None) { + $1 = newRef = NULL; + } else { + newRef = $input; + $1 = (void *)$input; + } + if (svn_swig_py_pool_set_owned_ref(obj0, (PyObject *)arg1->$1_name, newRef)) { + SWIG_fail; + } +} +#endif + /* ----------------------------------------------------------------------- Wrap the digest output for functions populating digests. */ diff -Nur subversion-1.3.1/subversion/bindings/swig/include/svn_types.swg.orig subversion-1.3.1.new/subversion/bindings/swig/include/svn_types.swg.orig --- subversion-1.3.1/subversion/bindings/swig/include/svn_types.swg.orig 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/include/svn_types.swg.orig 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,795 @@ +/* + * svn_types.swg : SWIG include file for svn_types.h + * + * ==================================================================== + * Copyright (c) 2000-2003 CollabNet. All rights reserved. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://subversion.tigris.org/license-1.html. + * If newer versions of this license are posted there, you may use a + * newer version instead, at your option. + * + * This software consists of voluntary contributions made by many + * individuals. For exact contribution history, see the revision + * history and logs, available at http://subversion.tigris.org/. + * ==================================================================== + */ + +/* This interface file only defines types and their related information. + There is no module associated with this interface file. */ + +%include apr.swg +%include exception.i + +/* ----------------------------------------------------------------------- + Create a typemap to define "type **" as OUT parameters. + + Note: SWIGTYPE is just a placeholder for "some arbitrary type". This + typemap will be applied onto a "real" type. +*/ +%typemap(python, in, numinputs=0) SWIGTYPE **OUTPARAM ($*1_type temp) { + $1 = ($1_ltype)&temp; +} +%typemap(perl5, in, numinputs=0) SWIGTYPE **OUTPARAM ($*1_type temp) { + $1 = ($1_ltype)&temp; +} +%typemap(ruby, in, numinputs=0) SWIGTYPE **OUTPARAM ($*1_type temp) { + temp = NULL; + $1 = ($1_ltype)&temp; +} + +%typemap(python, argout, fragment="t_output_helper") SWIGTYPE **OUTPARAM { + $result = t_output_helper($result, + svn_swig_NewPointerObj(*$1, $*1_descriptor, _global_svn_swig_py_pool)); +} +%typemap(perl5, argout) SWIGTYPE **OUTPARAM { + ST(argvi) = sv_newmortal(); + SWIG_MakePtr(ST(argvi++), (void *)*$1, $*1_descriptor,0); +} +%typemap(ruby, argout, fragment="output_helper") SWIGTYPE **OUTPARAM { + $result = output_helper($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); +} + +/* ----------------------------------------------------------------------- + %apply-ing of typemaps +*/ + +%apply SWIGTYPE **OUTPARAM { + svn_stream_t **, + svn_commit_info_t ** +}; + +%apply long *OUTPUT { svn_revnum_t * }; +%apply int *OUTPUT { svn_boolean_t * }; + +/* svn_fs_check_path() */ +%apply long *OUTPUT { svn_node_kind_t * }; + +/* svn_config_get_server_setting_int() */ +%apply long long *OUTPUT { apr_int64_t * }; + +/* ----------------------------------------------------------------------- + Create a typemap for specifying string args that may be NULL. +*/ +%typemap(python, in, parse="z") const char *MAY_BE_NULL ""; + +#ifdef SWIGPERL +%apply const char * { const char *MAY_BE_NULL }; +#endif + +%typemap(ruby, in) const char* MAY_BE_NULL +{ + if (NIL_P($input)) { + $1 = NULL; + } else { + $1 = StringValuePtr($input); + } +} + +%typemap(ruby, out) const char * +{ + if ($1) { + $result = rb_str_new2($1); + } else { + $result = Qnil; + } +} + +/* ----------------------------------------------------------------------- + const char *header_encoding + svn_diff_file_output_unified2 + svn_client_diff3 +*/ +%typemap(ruby, in) const char *header_encoding +{ + $1 = NULL; + + if (NIL_P($input)) { + } else if (TYPE($input) == T_FIXNUM) { + $1 = (char *)NUM2INT($input); + if (!($1 == APR_LOCALE_CHARSET || $1 == APR_DEFAULT_CHARSET)) { + $1 = NULL; + } + } else { + $1 = StringValuePtr($input); + } + + if (!$1) { + $1 = (char *)APR_LOCALE_CHARSET; + } +} + +/* ----------------------------------------------------------------------- + Input of scripting hash/dictionary (string => string) + converted to apr_hash_t (const char * => const char *) +*/ +%typemap(python, in) apr_hash_t *STRING_TO_STRING { + $1 = svn_swig_py_stringhash_from_dict ($input, _global_pool); +} +%typemap(perl5, in) apr_hash_t *STRING_TO_STRING { + $1 = svn_swig_pl_strings_to_hash ($input, _global_pool); +} +%typemap(ruby, in) apr_hash_t *STRING_TO_STRING { + $1 = svn_swig_rb_hash_to_apr_hash_string($input, _global_pool); +} + + +/* ----------------------------------------------------------------------- + Define a more refined 'memberin' typemap for 'const char *' members. This + is used in place of the 'char *' handler defined automatically. + + We need to do the free/malloc/strcpy special because of the const +*/ +%typemap(memberin) const char * { + apr_size_t len = strlen($input) + 1; + char *copied; + if ($1) free((char *)$1); + copied = malloc(len); + memcpy(copied, $input, len); + $1 = copied; +} + +/* ----------------------------------------------------------------------- + Specify how svn_error_t returns are turned into exceptions. +*/ +%typemap(python, out) svn_error_t * { + if ($1 != NULL) { + if ($1->apr_err != SVN_ERR_SWIG_PY_EXCEPTION_SET) + svn_swig_py_svn_exception($1); + else + svn_error_clear($1); + SWIG_fail; + } + Py_INCREF(Py_None); + $result = Py_None; +} + +%typemap(perl5,out) svn_error_t * { + if ($1) { + SV *exception_handler = perl_get_sv ("SVN::Error::handler", FALSE); + + if (SvOK(exception_handler)) { + SV *callback_result; + + svn_swig_pl_callback_thunk (CALL_SV, exception_handler, + &callback_result, "S", $1, + $1_descriptor); + } else { + $result = sv_newmortal(); + SWIG_MakePtr ($result, (void *)$1, $1_descriptor ,0); + argvi++; + } + } +} + +%typemap(ruby, out) svn_error_t * +{ + if ($1) { + svn_swig_rb_pop_pool(_global_svn_swig_rb_pool); + svn_swig_rb_handle_svn_error($1); + } + $result = Qnil; +} + +/* ----------------------------------------------------------------------- + Define an OUTPUT typemap for 'svn_filesize_t *'. For now, we'll + treat it as a 'long' even if that isn't entirely correct... +*/ +%typemap(python,in,numinputs=0) svn_filesize_t * (svn_filesize_t temp) + "$1 = &temp;"; + +%typemap(perl5,in,numinputs=0) svn_filesize_t * (svn_filesize_t temp) + "$1 = &temp;"; + +%typemap(ruby,in,numinputs=0) svn_filesize_t * (svn_filesize_t temp) + "$1 = &temp;"; + +%typemap(python,argout,fragment="t_output_helper") svn_filesize_t * + "$result = t_output_helper($result, + PyLong_FromLongLong((apr_int64_t) (*$1)));"; + +/* XXX: apply long long *OUTPUT doesn't track $1 correctly */ +%typemap(perl5,argout) svn_filesize_t * { + char temp[256]; + sprintf(temp,"%" APR_INT64_T_FMT, *$1); + ST(argvi) = sv_newmortal(); + sv_setpv((SV*)ST(argvi++), temp); +}; + +%typemap(ruby,argout,fragment="output_helper") svn_filesize_t * + "$result = output_helper($result, LL2NUM((apr_int64_t) (*$1)));"; + +/* ----------------------------------------------------------------------- + Define a general ptr/len typemap. This takes a single script argument + and expands it into a ptr/len pair for the native call. +*/ +%typemap(python, in) (const char *PTR, apr_size_t LEN) { + if (!PyString_Check($input)) { + PyErr_SetString(PyExc_TypeError, "expecting a string"); + SWIG_fail; + } + $1 = PyString_AS_STRING($input); + $2 = PyString_GET_SIZE($input); +} + +%typemap(perl5, in) (const char *PTR, apr_size_t LEN) { + if (SvPOK($input)) { + $1 = SvPV($input, $2); + } else { + /* set to 0 to avoid warning */ + $1 = 0; + $2 = 0; + SWIG_croak("Expecting a string"); + } +} + +/* ----------------------------------------------------------------------- + Handle retrieving the error message from svn_strerror +*/ + +%typemap(perl5,in,numinputs=0) (char *buf, apr_size_t bufsize) ( char temp[128] ) { + memset (temp,0,128); /* paranoia */ + $1 = temp; + $2 = 128; +} + +/* ----------------------------------------------------------------------- + Define a generic arginit mapping for pools. +*/ + +#ifdef SWIGPYTHON +%define svn_swig_py_pool_check(pool) + if (pool != NULL && !PyObject_HasAttrString(pool, (char *)"_mark_valid")) + { + int argnum = PyTuple_GET_SIZE(args); + SWIG_Python_TypeError(SWIG_TypePrettyName($descriptor), pool); + SWIG_arg_fail(argnum); + SWIG_fail; + } +%enddef +%define svn_swig_py_pool_create_subpool(py_pool, pool) + if (py_pool != NULL) { + pool = svn_pool_create(pool); + py_pool = svn_swig_NewPointerObj(pool, $descriptor, py_pool); + } +%enddef +#endif + +%typemap(python, default) apr_pool_t *(apr_pool_t *_global_pool, + PyObject *_global_svn_swig_py_pool, int _global_pool_is_default_pool) +{ + int argnum = PyTuple_GET_SIZE(args) - 1; + _global_pool_is_application_pool = 0; + _global_pool_is_default_pool = 1; + if (argnum >= 0) { + PyObject *input = PyTuple_GET_ITEM(args, argnum); + if (input != Py_None && + PyObject_HasAttrString(input, (char *)"_mark_valid")) { + _global_pool = svn_swig_MustGetPtr(input, $1_descriptor, argnum+1, NULL); + if (PyErr_Occurred()) { + _global_svn_swig_py_pool = NULL; + SWIG_fail; + } + _global_svn_swig_py_pool = input; + Py_XINCREF(_global_svn_swig_py_pool); + _global_pool_is_default_pool = 0; + } else { + if (PyErr_Occurred()) { + PyErr_Clear(); + } + svn_swig_get_application_pool(&_global_svn_swig_py_pool, &_global_pool); + svn_swig_py_pool_create_subpool(_global_svn_swig_py_pool, _global_pool); + } + } else { + svn_swig_get_application_pool(&_global_svn_swig_py_pool, &_global_pool); + svn_swig_py_pool_create_subpool(_global_svn_swig_py_pool, _global_pool); + } + $1 = _global_pool; + svn_swig_py_pool_check(_global_svn_swig_py_pool) +} + +%typemap(python, in) apr_pool_t * { + if ($input != Py_None && _global_pool_is_default_pool == 1) { + svn_swig_py_pool_check($input) + _global_pool = svn_swig_MustGetPtr($input, $1_descriptor, $svn_argnum, + NULL); + if (PyErr_Occurred()) { + SWIG_fail; + } + Py_XDECREF(_global_svn_swig_py_pool); + _global_svn_swig_py_pool = $input; + Py_XINCREF(_global_svn_swig_py_pool); + $1 = _global_pool; + } +} + +%typemap(python, freearg) apr_pool_t * { + Py_XDECREF(_global_svn_swig_py_pool); +} + +%typemap(perl5, in) apr_pool_t *pool ""; +%typemap(perl5, default) apr_pool_t *pool(apr_pool_t *_global_pool) { + _global_pool = $1 = svn_swig_pl_make_pool (ST(items-1)); +} +%typemap(ruby, in) apr_pool_t *pool ""; +%typemap(ruby, default) apr_pool_t *pool + (VALUE _global_svn_swig_rb_pool, apr_pool_t *_global_pool) +{ + svn_swig_rb_get_pool(argc, argv, self, &_global_svn_swig_rb_pool, &$1); + _global_pool = $1; + svn_swig_rb_push_pool(_global_svn_swig_rb_pool); +} + +%typemap(ruby, default) (svn_client_ctx_t *ctx, apr_pool_t *pool) + (VALUE _global_svn_swig_rb_pool, apr_pool_t *_global_pool) +{ + int adjusted_argc = argc; + VALUE *adjusted_argv = argv; + + svn_swig_rb_adjust_arg_for_client_ctx_and_pool(&adjusted_argc, + &adjusted_argv); + svn_swig_rb_get_pool(adjusted_argc, adjusted_argv, self, + &_global_svn_swig_rb_pool, &$2); + _global_pool = $2; + svn_swig_rb_push_pool(_global_svn_swig_rb_pool); +} + +%typemap(ruby, argout) apr_pool_t *pool +{ + svn_swig_rb_set_pool($result, _global_svn_swig_rb_pool); + svn_swig_rb_pop_pool(_global_svn_swig_rb_pool); +} + +#ifdef SWIGPERL +%apply apr_pool_t *pool { + apr_pool_t *dir_pool, + apr_pool_t *file_pool, + apr_pool_t *node_pool +}; +#endif + +#ifdef SWIGRUBY +%apply apr_pool_t *pool { + apr_pool_t *dir_pool, + apr_pool_t *file_pool, + apr_pool_t *node_pool +}; +#endif + + +/* ----------------------------------------------------------------------- + CALLBACK_BATON: Do not convert to C object from Ruby object. +*/ + +%typemap(ruby, in) void *CALLBACK_BATON +{ + $1 = (void *)$input; +} + + +/* ----------------------------------------------------------------------- + Callback: svn_log_message_receiver_t + svn_client_log() + svn_ra get_log() + svn_repos_get_logs() +*/ + +%typemap(python, in) (svn_log_message_receiver_t receiver, + void *receiver_baton) { + $1 = svn_swig_py_log_receiver; + $2 = (void *)$input; +} +%typemap(perl5, in) (svn_log_message_receiver_t receiver, + void *receiver_baton) { + $1 = svn_swig_pl_thunk_log_receiver; + $2 = (void *)$input; +} + +%typemap(ruby, 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); +} + +/* ----------------------------------------------------------------------- + Callback: svn_commit_callback_t + svn_ra get_commit_editor() + svn_repos_get_commit_editor() +*/ + +%typemap(perl5, in) (svn_commit_callback_t callback, void *callback_baton) { + $1 = svn_swig_pl_thunk_commit_callback; + $2 = (void *)$input; + svn_swig_pl_hold_ref_in_pool (_global_pool, $input); +}; + +%typemap(ruby, in) (svn_commit_callback_t callback, void *callback_baton) +{ + $1 = svn_swig_rb_commit_callback; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +}; + +%typemap(python, in) (svn_commit_callback2_t callback, void *callback_baton) +{ + $1 = svn_swig_py_commit_callback2; + $2 = (void *)$input; +} + +/* ----------------------------------------------------------------------- + Callback: svn_cancel_func_t +*/ + +%typemap(python, in) (svn_cancel_func_t cancel_func, void *cancel_baton) { + $1 = svn_swig_py_cancel_func; + $2 = $input; /* our function is the baton. */ +} + +%typemap(ruby, in) (svn_cancel_func_t cancel_func, void *cancel_baton) +{ + $1 = svn_swig_rb_cancel_func; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +/* ----------------------------------------------------------------------- + Callback: svn_info_receiver_t +*/ + +%typemap(ruby, in) (svn_info_receiver_t receiver, void *receiver_baton) +{ + $1 = svn_swig_rb_info_receiver; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +/* ----------------------------------------------------------------------- + Callback: svn_fs_warning_callback_t +*/ + +%typemap(ruby, in) (svn_fs_warning_callback_t warning, void *warning_baton) +{ + VALUE baton = svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); + svn_swig_rb_fs_warning_callback_baton_register(baton, _global_pool); + $1 = svn_swig_rb_fs_warning_callback; + $2 = (void *)baton; +} + +/* ----------------------------------------------------------------------- + svn_stream_t interoperability with language native io handles +*/ + +%typemap(python, in) svn_stream_t *WRAPPED_STREAM { + $1 = svn_swig_py_make_stream ($input, _global_pool); +} + +%typemap(perl5, in) svn_stream_t * { + svn_swig_pl_make_stream (&$1, $input); +} + +%typemap(perl5, out) svn_stream_t * { + $result = svn_swig_pl_from_stream ($1); + argvi++; +} + +%typemap(perl5, argout) svn_stream_t ** { + $result = svn_swig_pl_from_stream (*$1); + argvi++; +} + +%typemap(ruby, in) svn_stream_t * { + $1 = svn_swig_rb_make_stream($input); +} + +#ifdef SWIGPYTHON +%typemap(in) (svn_commit_callback_t callback, void *callback_baton) +{ + $1 = svn_swig_py_commit_callback; + $2 = (void *)$input; +} +#endif + +#ifdef SWIGPYTHON +%typemap(in) (svn_commit_callback_t callback, void *callback_baton) +{ + $1 = svn_swig_py_commit_callback; + $2 = (void *)$input; +} +#endif + +/* ----------------------------------------------------------------------- + Mapper to automatically turn Python objects into void* batons on assignment +*/ + +#ifdef SWIGPYTHON +%typemap(in) void *PY_AS_VOID (PyObject *newRef) { + newRef = $input; + if ($input == Py_None) { + $1 = newRef = NULL; + } else { + newRef = $input; + $1 = (void *)$input; + } + if (svn_swig_py_pool_set_owned_ref(obj0, (PyObject *)arg1->$1_name, newRef)) { + SWIG_fail; + } +} +#endif + +/* ----------------------------------------------------------------------- + Wrap the digest output for functions populating digests. +*/ + +%typemap(in, numinputs=0) unsigned char digest[ANY] + ($*1_type temp[APR_MD5_DIGESTSIZE]) { + $1 = ($1_ltype)temp; +} + +%typemap(python, argout, fragment="t_output_helper") unsigned char digest[ANY] +{ + $result = t_output_helper($result, + PyString_FromString(svn_md5_digest_to_cstring ($1, _global_pool))); +} + +%typemap(perl5, argout) unsigned char digest[ANY] { + ST(argvi) = sv_newmortal(); + sv_setpv((SV*)ST(argvi++), svn_md5_digest_to_cstring ($1,_global_pool)); +} + +%typemap(ruby, argout, fragment="output_helper") unsigned char digest[ANY] +{ + $result = output_helper($result, + rb_str_new2(svn_md5_digest_to_cstring($1, _global_pool))); +} + +/* svn_md5_* functions takes const ones as input */ +%typemap(perl5, in) const unsigned char digest[] { + SWIG_ConvertPtr($input, (void **)&$1, $1_descriptor, 0); +} +%typemap(perl5, argout) const unsigned char digest[] {} + +/* + svn_txdelta_send_stream() uses *digest not digest[] . + svn_txdelta_apply() uses *result_digest not digest[] . +*/ + +%typemap(in, numinputs=0) unsigned char *result_digest { + $1 = (unsigned char *)apr_palloc(_global_pool, APR_MD5_DIGESTSIZE); +} + +%typemap(perl5, argout) unsigned char *result_digest { + ST(argvi) = sv_newmortal(); + ST(argvi++) = svn_swig_pl_from_md5($1); +} + +%apply unsigned char digest[ANY] { + unsigned char *digest +}; + +#ifndef SWIGPERL +%apply unsigned char digest[ANY] { + unsigned char *result_digest +}; +#endif + +/* ----------------------------------------------------------------------- + useful convertors for svn_opt_revision_t +*/ +%typemap(perl5, in) svn_opt_revision_t * (svn_opt_revision_t rev) { + $1 = &rev; + if ($input == NULL || $input == &PL_sv_undef || !SvOK($input)) { + rev.kind = svn_opt_revision_unspecified; + } + else if (sv_isobject($input) && sv_derived_from($input, "_p_svn_opt_revision_t")) { + SWIG_ConvertPtr($input, (void **)&$1, $1_descriptor, 0); + } + else if (looks_like_number($input)) { + rev.kind = svn_opt_revision_number; + rev.value.number = SvIV($input); + } + else if (SvPOK($input)) { + char *input = SvPV_nolen($input); + if (strcasecmp(input, "BASE") == 0) + rev.kind = svn_opt_revision_base; + else if (strcasecmp(input, "HEAD") == 0) + rev.kind = svn_opt_revision_head; + else if (strcasecmp(input, "WORKING") == 0) + rev.kind = svn_opt_revision_working; + else if (strcasecmp(input, "COMMITTED") == 0) + rev.kind = svn_opt_revision_committed; + else if (strcasecmp(input, "PREV") == 0) + rev.kind = svn_opt_revision_previous; + else if (*input == '{') { + svn_boolean_t matched; + apr_time_t tm; + svn_error_t *err; + + char *end = strchr(input,'}'); + if (!end) + SWIG_croak("unknown opt_revision_t type"); + *end = '\0'; + err = svn_parse_date (&matched, &tm, input + 1, apr_time_now(), + svn_swig_pl_make_pool ((SV *)NULL)); + if (err) { + svn_error_clear (err); + SWIG_croak("unknown opt_revision_t type"); + } + if (!matched) + SWIG_croak("unknown opt_revision_t type"); + + rev.kind = svn_opt_revision_date; + rev.value.date = tm; + } else + SWIG_croak("unknown opt_revision_t type"); + } else + SWIG_croak("unknown opt_revision_t type"); +} + +%typemap(ruby, in) svn_opt_revision_t * (svn_opt_revision_t rev) { + $1 = &rev; + svn_swig_rb_set_revision(&rev, $input); +} + +/* ----------------------------------------------------------------------- + apr_hash_t **dirents + svn_client_ls() + svn_io_get_dirents() + svn_ra get_dir() +*/ + +%typemap(python,in,numinputs=0) apr_hash_t **dirents = apr_hash_t **OUTPUT; +%typemap(python,argout,fragment="t_output_helper") apr_hash_t **dirents { + $result = t_output_helper($result, svn_swig_py_convert_hash(*$1, + $descriptor(svn_dirent_t *), _global_svn_swig_py_pool)); +} + +%typemap(perl5,in,numinputs=0) apr_hash_t **dirents = apr_hash_t **OUTPUT; +%typemap(perl5,argout) apr_hash_t **dirents { + ST(argvi++) = svn_swig_pl_convert_hash + (*$1, $descriptor(svn_dirent_t *)); +} + +%typemap(ruby, in, numinputs=0) apr_hash_t **dirents = apr_hash_t **OUTPUT; +%typemap(ruby, argout, fragment="output_helper") apr_hash_t **dirents +{ + $result = output_helper($result, + svn_swig_rb_apr_hash_to_hash_swig_type + (*$1, "svn_dirent_t *")); +} + +/* ----------------------------------------------------------------------- + apr_hash_t **locks + svn_client_ls3() + svn_repos_fs_get_locks() + svn_ra_get_locks() +*/ + +%typemap(ruby, in, numinputs=0) apr_hash_t **locks = apr_hash_t **OUTPUT; +%typemap(ruby, argout, fragment="output_helper") apr_hash_t **locks +{ + $result = output_helper($result, + svn_swig_rb_apr_hash_to_hash_swig_type + (*$1, "svn_lock_t *")); +} + +/* ----------------------------------------------------------------------- + apr_array_header_t *location_revisions + svn_repos_trace_node_locations() + svn_ra_get_locations() +*/ + +%typemap(ruby, in) apr_array_header_t *location_revisions +{ + $1 = svn_swig_rb_array_to_apr_array_revnum($input, _global_pool); +} + +/* ----------------------------------------------------------------------- + apr_hash_t **locations + svn_repos_trace_node_locations() + svn_ra_get_locations() +*/ + +%typemap(ruby, in, numinputs=0) apr_hash_t **locations = apr_hash_t **OUTPUT; +%typemap(ruby, argout) apr_hash_t **locations +{ + $result = svn_swig_rb_apr_revnum_key_hash_to_hash_string(*$1); +} + +/* ----------------------------------------------------------------------- + Special boolean mapping for ruby. +*/ + +%typemap(ruby, in) svn_boolean_t "$1 = RTEST($input);"; +%typemap(ruby, out, fragment="output_helper") svn_boolean_t +{ + $result = output_helper($result, $1 ? Qtrue : Qfalse); +} + +%typemap(ruby, in, numinputs=0) svn_boolean_t * (svn_boolean_t temp) +{ + $1 = &temp; +} + +%typemap(ruby, argout, fragment="output_helper") svn_boolean_t * +{ + $result = output_helper($result, *$1 ? Qtrue : Qfalse); +} + +/* ----------------------------------------------------------------------- + Handle python thread locking. + + Swig doesn't allow us to specify a language in the %exception command, + so we have to use #ifdefs for the python-specific parts. +*/ + +%exception { +#ifdef SWIGPYTHON + svn_swig_py_release_py_lock(); +#endif + $action +#ifdef SWIGPYTHON + svn_swig_py_acquire_py_lock(); +#endif +} + + +/* ----------------------------------------------------------------------- + handle config and fs_config in svn_{fs,repos}_create +*/ + + +%typemap(ruby, in) apr_hash_t *config (apr_hash_t *temp) +{ + if (NIL_P($input)) { + $1 = NULL; + } else { + $1 = svn_swig_rb_hash_to_apr_hash_swig_type($input, "svn_config_t *", _global_pool); + } +} +%typemap(ruby, in) apr_hash_t *fs_config +{ + if (NIL_P($input)) { + $1 = NULL; + } else { + $1 = svn_swig_rb_hash_to_apr_hash_string($input, _global_pool); + } +} + +/* ----------------------------------------------------------------------- */ + +%{ +#ifdef SWIGPYTHON +#include "swigutil_py.h" +#endif + +#ifdef SWIGPERL +#include "swigutil_pl.h" +#endif + +#ifdef SWIGRUBY +#include +#include +#include "swigutil_rb.h" +#endif +%} + +%include svn_time_h.swg +%include svn_types_h.swg diff -Nur subversion-1.3.1/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c subversion-1.3.1.new/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c --- subversion-1.3.1/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c 2006-03-05 20:55:14.000000000 +0000 +++ subversion-1.3.1.new/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c 2006-07-05 01:05:43.000000000 +0100 @@ -30,6 +30,7 @@ #include #include +#include "svn_client.h" #include "svn_string.h" #include "svn_opt.h" #include "svn_delta.h" @@ -72,11 +73,13 @@ #ifdef ACQUIRE_PYTHON_LOCK PyThreadState *thread_state; - if (_saved_thread_key == NULL) { - /* Obviously, creating a top-level pool for this is pretty stupid. */ - apr_pool_create(&_saved_thread_pool, NULL); - apr_threadkey_private_create(&_saved_thread_key, NULL, _saved_thread_pool); - } + if (_saved_thread_key == NULL) + { + /* Obviously, creating a top-level pool for this is pretty stupid. */ + apr_pool_create(&_saved_thread_pool, NULL); + apr_threadkey_private_create(&_saved_thread_key, NULL, + _saved_thread_pool); + } thread_state = PyEval_SaveThread(); apr_threadkey_private_set(thread_state, _saved_thread_key); @@ -103,6 +106,8 @@ static PyObject *_global_svn_swig_py_pool = NULL; static char assertValid[] = "assert_valid"; static char parentPool[] = "_parent_pool"; +static char addOwnedRef[] = "_add_owned_ref"; +static char removeOwnedRef[] = "_remove_owned_ref"; static char wrap[] = "_wrap"; static char unwrap[] = "_unwrap"; static char setParentPool[] = "set_parent_pool"; @@ -122,7 +127,7 @@ } /* Set the application pool */ -void svn_swig_py_set_application_pool(PyObject *py_pool, apr_pool_t *pool) +void svn_swig_py_set_application_pool(PyObject *py_pool, apr_pool_t *pool) { _global_pool = pool; _global_svn_swig_py_pool = py_pool; @@ -147,55 +152,106 @@ { PyObject *result; - if (*proxy != NULL) { - if (pool == NULL) { - if (PyObject_HasAttrString(*proxy, setParentPool)) { - result = PyObject_CallMethod(*proxy, setParentPool, emptyTuple); - if (result == NULL) { - return 1; + if (*proxy != NULL) + { + if (pool == NULL) + { + if (PyObject_HasAttrString(*proxy, setParentPool)) + { + result = PyObject_CallMethod(*proxy, setParentPool, emptyTuple); + if (result == NULL) + return 1; + Py_DECREF(result); + } + } + else + { + result = PyObject_CallMethod(pool, wrap, objectTuple, *proxy); + Py_DECREF(*proxy); + *proxy = result; } - Py_DECREF(result); - } - } else { - result = PyObject_CallMethod(pool, wrap, objectTuple, *proxy); - Py_DECREF(*proxy); - *proxy = result; } - } return 0; } + +/* Get the parent pool of a proxy object, or return the global application + * pool if one is not set. Returns a BORROWED reference! */ +static PyObject *proxy_get_pool(PyObject *proxy) +{ + PyObject *result; + if (PyObject_HasAttrString(proxy, parentPool)) + { + result = PyObject_GetAttrString(proxy, parentPool); + Py_DECREF(result); + } + else + { + result = _global_svn_swig_py_pool; + } + return result; +} + +/* Change an 'owned reference' allocated in a pool from oldRef to newRef. + * If oldRef is non-NULL and present in the parent pool of proxy, it is removed. + */ +int svn_swig_py_pool_set_owned_ref(PyObject *proxy, PyObject *oldRef, + PyObject *newRef) +{ + PyObject *temp; + PyObject *py_pool = proxy_get_pool(proxy); + + if (oldRef != NULL) + { + temp = PyObject_CallMethod(py_pool, removeOwnedRef, objectTuple, oldRef); + if (temp == NULL) + return 1; + else + Py_DECREF(temp); + } + if (newRef != NULL) + { + temp = PyObject_CallMethod(py_pool, addOwnedRef, objectTuple, newRef); + if (temp == NULL) + return 1; + else + Py_DECREF(temp); + } + return 0; +} /* Wrapper for SWIG_TypeQuery */ #define svn_swig_TypeQuery(x) SWIG_TypeQuery(x) /** Wrapper for SWIG_NewPointerObj */ -PyObject *svn_swig_NewPointerObj(void *obj, swig_type_info *type, +PyObject *svn_swig_NewPointerObj(void *obj, swig_type_info *type, PyObject *pool) { PyObject *proxy = SWIG_NewPointerObj(obj, type, 0); - if (proxy == NULL) { - return NULL; - } - - if (proxy_set_pool(&proxy, pool)) { - Py_DECREF(proxy); + if (proxy == NULL) return NULL; - } + + if (proxy_set_pool(&proxy, pool)) + { + Py_DECREF(proxy); + return NULL; + } return proxy; } /** svn_swig_NewPointerObj, except a string is used to describe the type */ -static PyObject *svn_swig_NewPointerObjString(void *ptr, const char *type, +static PyObject *svn_swig_NewPointerObjString(void *ptr, const char *type, PyObject *py_pool) { swig_type_info *typeinfo = svn_swig_TypeQuery(type); - if (typeinfo == NULL) { - PyErr_SetString(PyExc_TypeError, "Cannot find required typeobject"); - return NULL; - } + if (typeinfo == NULL) + { + PyErr_SetString(PyExc_TypeError, "Cannot find required typeobject"); + return NULL; + } + /* ### cache the swig_type_info at some point? */ return svn_swig_NewPointerObj(ptr, typeinfo, py_pool); } @@ -203,20 +259,21 @@ /** Wrapper for SWIG_ConvertPtr */ int svn_swig_ConvertPtr(PyObject *input, void **obj, swig_type_info *type) { - if (PyObject_HasAttrString(input, assertValid)) { - PyObject *result = PyObject_CallMethod(input, assertValid, emptyTuple); - if (result == NULL) { - return 1; - } - Py_DECREF(result); - } - if (PyObject_HasAttrString(input, unwrap)) { - input = PyObject_CallMethod(input, unwrap, emptyTuple); - if (input == NULL) { - return 1; + if (PyObject_HasAttrString(input, assertValid)) + { + PyObject *result = PyObject_CallMethod(input, assertValid, emptyTuple); + if (result == NULL) + return 1; + Py_DECREF(result); + } + if (PyObject_HasAttrString(input, unwrap)) + { + input = PyObject_CallMethod(input, unwrap, emptyTuple); + if (input == NULL) + return 1; + Py_DECREF(input); } - Py_DECREF(input); - } + return SWIG_ConvertPtr(input, obj, type, SWIG_POINTER_EXCEPTION | 0); } @@ -231,31 +288,28 @@ void *svn_swig_MustGetPtr(void *input, swig_type_info *type, int argnum, PyObject **py_pool) { - if (PyObject_HasAttrString(input, assertValid)) { - PyObject *result = PyObject_CallMethod(input, assertValid, emptyTuple); - if (result == NULL) { - return NULL; + if (PyObject_HasAttrString(input, assertValid)) + { + PyObject *result = PyObject_CallMethod(input, assertValid, emptyTuple); + if (result == NULL) + return NULL; + Py_DECREF(result); } - Py_DECREF(result); - } - if (py_pool != NULL) { - if (PyObject_HasAttrString(input, parentPool)) { - *py_pool = PyObject_GetAttrString(input, parentPool); - Py_DECREF(*py_pool); - } else { - *py_pool = _global_svn_swig_py_pool; - } - } - if (PyObject_HasAttrString(input, unwrap)) { - input = PyObject_CallMethod(input, unwrap, emptyTuple); - if (input == NULL) { - return NULL; + + if (py_pool != NULL) + *py_pool = proxy_get_pool((PyObject *) input); + + if (PyObject_HasAttrString(input, unwrap)) + { + input = PyObject_CallMethod(input, unwrap, emptyTuple); + if (input == NULL) + return NULL; + Py_DECREF((PyObject *) input); } - Py_DECREF((PyObject *) input); - } + return SWIG_MustGetPtr(input, type, argnum, SWIG_POINTER_EXCEPTION | 0); } - + /*** Custom SubversionException stuffs. ***/ @@ -283,7 +337,7 @@ } void svn_swig_py_svn_exception(svn_error_t *err) -{ +{ PyObject *exc_ob, *apr_err_ob; if (err == NULL) @@ -295,7 +349,7 @@ return; /* Instantiate a SubversionException object. */ - exc_ob = PyObject_CallFunction(SubversionException, (char *)"sO", + exc_ob = PyObject_CallFunction(SubversionException, (char *)"sO", err->message, apr_err_ob); if (exc_ob == NULL) { @@ -340,7 +394,7 @@ static PyObject *make_ob_fs_root(svn_fs_root_t *ptr, PyObject *py_pool) { return svn_swig_NewPointerObjString(ptr, "svn_fs_root_t *", py_pool); -} +} /***/ /* Conversion from Python single objects (not hashes/lists/etc.) to @@ -349,20 +403,22 @@ { if (ob == Py_None) return NULL; - if (! PyString_Check(ob)) { - PyErr_SetString(PyExc_TypeError, "not a string"); - return NULL; - } + if (! PyString_Check(ob)) + { + PyErr_SetString(PyExc_TypeError, "not a string"); + return NULL; + } return apr_pstrdup(pool, PyString_AS_STRING(ob)); } static svn_string_t *make_svn_string_from_ob(PyObject *ob, apr_pool_t *pool) { if (ob == Py_None) return NULL; - if (! PyString_Check(ob)) { - PyErr_SetString(PyExc_TypeError, "not a string"); - return NULL; - } + if (! PyString_Check(ob)) + { + PyErr_SetString(PyExc_TypeError, "not a string"); + return NULL; + } return svn_string_create(PyString_AS_STRING(ob), pool); } @@ -381,25 +437,28 @@ if (dict == NULL) return NULL; - for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) { + for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) + { const void *key; void *val; PyObject *value; apr_hash_this(hi, &key, NULL, &val); value = (*converter_func)(val, ctx, py_pool); - if (value == NULL) { + if (value == NULL) + { Py_DECREF(dict); return NULL; - } + } /* ### gotta cast this thing cuz Python doesn't use "const" */ - if (PyDict_SetItemString(dict, (char *)key, value) == -1) { + if (PyDict_SetItemString(dict, (char *)key, value) == -1) + { Py_DECREF(value); Py_DECREF(dict); return NULL; - } + } Py_DECREF(value); - } + } return dict; } @@ -446,7 +505,7 @@ url = Py_None; Py_INCREF(Py_None); } - + if (item->copyfrom_url) cf_url = PyString_FromString(item->copyfrom_url); else @@ -454,7 +513,7 @@ cf_url = Py_None; Py_INCREF(Py_None); } - + kind = PyInt_FromLong(item->kind); rev = PyInt_FromLong(item->revision); state = PyInt_FromLong(item->state_flags); @@ -485,6 +544,52 @@ return convert_hash(hash, convert_svn_string_t, NULL, NULL); } +static PyObject *proparray_to_dict(const apr_array_header_t *array) +{ + PyObject *dict = PyDict_New(); + int i; + + if (dict == NULL) + return NULL; + + for (i = 0; i < array->nelts; ++i) + { + svn_prop_t prop; + PyObject *py_key, *py_value; + + prop = APR_ARRAY_IDX(array, i, svn_prop_t); + + py_key = PyString_FromString(prop.name); + if (py_key == NULL) + goto error; + + if (prop.value == NULL) + { + py_value = Py_None; + Py_INCREF(Py_None); + } + else + { + py_value = PyString_FromStringAndSize((void *)prop.value->data, + prop.value->len); + if (py_value == NULL) + { + Py_DECREF(py_key); + goto error; + } + } + + PyDict_SetItem(dict, py_key, py_value); + } + + return dict; + + error: + Py_DECREF(dict); + return NULL; + +} + PyObject *svn_swig_py_locationhash_to_dict(apr_hash_t *hash) { @@ -496,7 +601,7 @@ if (dict == NULL) return NULL; - for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) + for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) { const void *k; void *v; @@ -510,12 +615,13 @@ return NULL; } value = PyString_FromString((char *)v); - if (value == NULL) { + if (value == NULL) + { Py_DECREF(key); Py_DECREF(dict); return NULL; - } - if (PyDict_SetItem(dict, key, value) == -1) + } + if (PyDict_SetItem(dict, key, value) == -1) { Py_DECREF(value); Py_DECREF(dict); @@ -527,11 +633,11 @@ return dict; } -PyObject *svn_swig_py_convert_hash(apr_hash_t *hash, swig_type_info *type, +PyObject *svn_swig_py_convert_hash(apr_hash_t *hash, swig_type_info *type, PyObject *py_pool) { return convert_hash(hash, convert_to_swigtype, type, py_pool); -} +} #define DECLARE_SWIG_CONSTRUCTOR(type, dup) \ static PyObject *make_ob_##type(void *value) \ @@ -543,13 +649,16 @@ return svn_swig_NewPointerObjString(new_value, "svn_" #type "_t *", \ new_py_pool); \ } - + DECLARE_SWIG_CONSTRUCTOR(txdelta_window, svn_txdelta_window_dup) DECLARE_SWIG_CONSTRUCTOR(log_changed_path, svn_log_changed_path_dup) DECLARE_SWIG_CONSTRUCTOR(wc_status, svn_wc_dup_status) DECLARE_SWIG_CONSTRUCTOR(lock, svn_lock_dup) DECLARE_SWIG_CONSTRUCTOR(auth_ssl_server_cert_info, 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) @@ -562,14 +671,15 @@ PyObject *list = PyList_New(0); char *s; - while ((s = *strings++) != NULL) { + while ((s = *strings++) != NULL) + { PyObject *ob = PyString_FromString(s); if (ob == NULL) goto error; if (PyList_Append(list, ob) == -1) goto error; - } + } return list; @@ -584,16 +694,17 @@ apr_hash_t *hash; PyObject *keys; int i, num_keys; - + if (dict == Py_None) return NULL; - if (!PyDict_Check(dict)) { - PyErr_SetString(PyExc_TypeError, "not a dictionary"); - return NULL; - } + if (!PyDict_Check(dict)) + { + PyErr_SetString(PyExc_TypeError, "not a dictionary"); + return NULL; + } - hash = apr_hash_make(pool); + hash = apr_hash_make(pool); keys = PyDict_Keys(dict); num_keys = PyList_Size(keys); for (i = 0; i < num_keys; i++) @@ -606,7 +717,7 @@ Py_DECREF(value); if (! (propname && propval)) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_TypeError, "dictionary keys/values aren't strings"); Py_DECREF(keys); return NULL; @@ -628,12 +739,13 @@ if (dict == Py_None) return NULL; - if (!PyDict_Check(dict)) { - PyErr_SetString(PyExc_TypeError, "not a dictionary"); - return NULL; - } + if (!PyDict_Check(dict)) + { + PyErr_SetString(PyExc_TypeError, "not a dictionary"); + return NULL; + } - hash = apr_hash_make(pool); + hash = apr_hash_make(pool); keys = PyDict_Keys(dict); num_keys = PyList_Size(keys); for (i = 0; i < num_keys; i++) @@ -646,7 +758,7 @@ Py_DECREF(value); if (! (propname && propval)) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_TypeError, "dictionary keys/values aren't strings"); Py_DECREF(keys); return NULL; @@ -664,27 +776,30 @@ int targlen; apr_array_header_t *temp; - if (!PySequence_Check(source)) { + if (!PySequence_Check(source)) + { PyErr_SetString(PyExc_TypeError, "not a sequence"); return NULL; - } + } targlen = PySequence_Length(source); temp = apr_array_make(pool, targlen, sizeof(const char *)); /* APR_ARRAY_IDX doesn't actually increment the array item count (like, say, apr_array_push would). */ temp->nelts = targlen; - while (targlen--) { + while (targlen--) + { PyObject *o = PySequence_GetItem(source, targlen); if (o == NULL) return NULL; - if (!PyString_Check(o)) { + if (!PyString_Check(o)) + { Py_DECREF(o); PyErr_SetString(PyExc_TypeError, "not a string"); return NULL; - } + } APR_ARRAY_IDX(temp, targlen, const char *) = PyString_AS_STRING(o); Py_DECREF(o); - } + } return temp; } @@ -695,32 +810,37 @@ int targlen; apr_array_header_t *temp; - if (!PySequence_Check(source)) { + if (!PySequence_Check(source)) + { PyErr_SetString(PyExc_TypeError, "not a sequence"); return NULL; - } + } targlen = PySequence_Length(source); temp = apr_array_make(pool, targlen, sizeof(svn_revnum_t)); /* APR_ARRAY_IDX doesn't actually increment the array item count (like, say, apr_array_push would). */ temp->nelts = targlen; - while (targlen--) { + while (targlen--) + { PyObject *o = PySequence_GetItem(source, targlen); if (o == NULL) return NULL; - if (PyLong_Check(o)) { - APR_ARRAY_IDX(temp, targlen, svn_revnum_t) = + if (PyLong_Check(o)) + { + APR_ARRAY_IDX(temp, targlen, svn_revnum_t) = (svn_revnum_t)PyLong_AsLong(o); - } - else if (PyInt_Check(o)) { - APR_ARRAY_IDX(temp, targlen, svn_revnum_t) = + } + else if (PyInt_Check(o)) + { + APR_ARRAY_IDX(temp, targlen, svn_revnum_t) = (svn_revnum_t)PyInt_AsLong(o); - } - else { + } + else + { Py_DECREF(o); PyErr_SetString(PyExc_TypeError, "not an integer type"); return NULL; - } + } Py_DECREF(o); } return temp; @@ -737,13 +857,14 @@ PyObject *list = PyList_New(array->nelts); int i; - for (i = 0; i < array->nelts; ++i) { - PyObject *ob = + for (i = 0; i < array->nelts; ++i) + { + PyObject *ob = PyString_FromString(APR_ARRAY_IDX(array, i, const char *)); if (ob == NULL) goto error; PyList_SET_ITEM(list, i, ob); - } + } return list; error: @@ -757,13 +878,14 @@ PyObject *list = PyList_New(array->nelts); int i; - for (i = 0; i < array->nelts; ++i) { - PyObject *ob + for (i = 0; i < array->nelts; ++i) + { + PyObject *ob = PyInt_FromLong(APR_ARRAY_IDX(array, i, svn_revnum_t)); if (ob == NULL) goto error; PyList_SET_ITEM(list, i, ob); - } + } return list; error: @@ -778,13 +900,14 @@ PyObject *list = PyList_New(array->nelts); int i; - for (i = 0; i < array->nelts; ++i) { + for (i = 0; i < array->nelts; ++i) + { PyObject *ob = convert_svn_client_commit_item_t (APR_ARRAY_IDX(array, i, svn_client_commit_item_t *), NULL); if (ob == NULL) goto error; PyList_SET_ITEM(list, i, ob); - } + } return list; error: @@ -829,8 +952,8 @@ PyObject *baton; /* the dir/file baton (or NULL for edit baton) */ } item_baton; -static item_baton *make_baton(apr_pool_t *pool, - PyObject *editor, +static item_baton *make_baton(apr_pool_t *pool, + PyObject *editor, PyObject *baton) { item_baton *newb = apr_palloc(pool, sizeof(*newb)); @@ -846,7 +969,7 @@ return newb; } -static svn_error_t *close_baton(void *baton, +static svn_error_t *close_baton(void *baton, const char *method) { item_baton *ib = baton; @@ -907,7 +1030,7 @@ /* there is no return value, so just toss this object (probably Py_None) */ Py_DECREF(result); err = SVN_NO_ERROR; - + finished: svn_swig_py_release_py_lock(); return err; @@ -1028,7 +1151,7 @@ /* make_baton takes our 'result' reference */ *child_baton = make_baton(dir_pool, ib->editor, result); err = SVN_NO_ERROR; - + finished: svn_swig_py_release_py_lock(); return err; @@ -1048,7 +1171,7 @@ /* ### python doesn't have 'const' on the method name and format */ if ((result = PyObject_CallMethod(ib->editor, (char *)"change_dir_prop", (char *)"Oss#O&", ib->baton, name, - value ? value->data : NULL, + value ? value->data : NULL, value ? value->len : 0, make_ob_pool, pool)) == NULL) { @@ -1113,7 +1236,7 @@ item_baton *ib = parent_baton; PyObject *result; svn_error_t *err; - + svn_swig_py_acquire_py_lock(); /* ### python doesn't have 'const' on the method name and format */ @@ -1159,7 +1282,7 @@ { /* invoke the handler with the window */ /* ### python doesn't have 'const' on the format */ - result = PyObject_CallFunction(handler, (char *)"O&", + result = PyObject_CallFunction(handler, (char *)"O&", make_ob_txdelta_window, window); } @@ -1178,7 +1301,7 @@ return err; } -static svn_error_t *apply_textdelta(void *file_baton, +static svn_error_t *apply_textdelta(void *file_baton, const char *base_checksum, apr_pool_t *pool, svn_txdelta_window_handler_t *handler, @@ -1238,7 +1361,7 @@ /* ### python doesn't have 'const' on the method name and format */ if ((result = PyObject_CallMethod(ib->editor, (char *)"change_file_prop", (char *)"Oss#O&", ib->baton, name, - value ? value->data : NULL, + value ? value->data : NULL, value ? value->len : 0, make_ob_pool, pool)) == NULL) { @@ -1249,7 +1372,7 @@ /* there is no return value, so just toss this object (probably Py_None) */ Py_DECREF(result); err = SVN_NO_ERROR; - + finished: svn_swig_py_release_py_lock(); return err; @@ -1446,19 +1569,30 @@ return err; } +static svn_error_t * +close_handler_pyio(void *baton) +{ + PyObject *py_io = baton; + Py_DECREF(py_io); + return SVN_NO_ERROR; +} + + svn_stream_t * svn_swig_py_make_stream (PyObject *py_io, apr_pool_t *pool) { svn_stream_t *stream; /* Borrow the caller's reference to py_io - this is safe only because the - * caller must have a reference in order to pass the object into the + * caller must have a reference in order to pass the object into the * bindings, and we will be finished with the py_io object before we return * to python. I.e. DO NOT STORE AWAY THE RESULTING svn_stream_t * for use * over multiple calls into the bindings. */ + Py_INCREF(py_io); stream = svn_stream_create (py_io, pool); svn_stream_set_read (stream, read_handler_pyio); svn_stream_set_write (stream, write_handler_pyio); + svn_stream_set_close (stream, close_handler_pyio); return stream; } @@ -1481,11 +1615,11 @@ return; svn_swig_py_acquire_py_lock(); - if ((result = PyObject_CallFunction(function, - (char *)"(siisiii)", + if ((result = PyObject_CallFunction(function, + (char *)"(siisiii)", path, action, kind, mime_type, - content_state, prop_state, + content_state, prop_state, revision)) == NULL) { err = callback_exception_error(); @@ -1506,6 +1640,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) @@ -1534,7 +1703,7 @@ /* Our error has no place to go. :-( */ if (err) svn_error_clear(err); - + svn_swig_py_release_py_lock(); } @@ -1587,7 +1756,7 @@ return SVN_NO_ERROR; svn_swig_py_acquire_py_lock(); - + if ((result = PyObject_CallFunction(function, (char *)"O&O&", make_ob_lock, lock, make_ob_pool, pool)) == NULL) @@ -1637,7 +1806,7 @@ Py_INCREF(Py_None); } - if ((result = PyObject_CallFunction(function, + if ((result = PyObject_CallFunction(function, (char *)"OO&", cmt_items, make_ob_pool, pool)) == NULL) @@ -1655,7 +1824,7 @@ *log_msg = NULL; err = SVN_NO_ERROR; } - else if (PyString_Check(result)) + else if (PyString_Check(result)) { *log_msg = apr_pstrdup(pool, PyString_AS_STRING(result)); Py_DECREF(result); @@ -1690,21 +1859,23 @@ return SVN_NO_ERROR; svn_swig_py_acquire_py_lock(); - + py_pool = make_ob_pool(pool); - if (py_pool == NULL) { - err = callback_exception_error(); - goto finished; - } + if (py_pool == NULL) + { + err = callback_exception_error(); + goto finished; + } py_root = make_ob_fs_root(root, py_pool); - if (py_root == NULL) { - Py_DECREF(py_pool); - err = callback_exception_error(); - goto finished; - } + if (py_root == NULL) + { + Py_DECREF(py_pool); + err = callback_exception_error(); + goto finished; + } - if ((result = PyObject_CallFunction(function, - (char *)"OsO", + if ((result = PyObject_CallFunction(function, + (char *)"OsO", py_root, path, py_pool)) == NULL) { err = callback_exception_error(); @@ -1740,9 +1911,9 @@ return SVN_NO_ERROR; svn_swig_py_acquire_py_lock(); - if ((result = PyObject_CallFunction(function, - (char *)"slO&", - path, revision, + if ((result = PyObject_CallFunction(function, + (char *)"slO&", + path, revision, make_ob_pool, pool)) == NULL) { err = callback_exception_error(); @@ -1770,17 +1941,18 @@ PyObject *result, *py_pool; PyObject *chpaths; svn_error_t *err = SVN_NO_ERROR; - + if ((receiver == NULL) || (receiver == Py_None)) return SVN_NO_ERROR; svn_swig_py_acquire_py_lock(); py_pool = make_ob_pool(pool); - if (py_pool == NULL) { - err = callback_exception_error(); - goto finished; - } + if (py_pool == NULL) + { + err = callback_exception_error(); + goto finished; + } if (changed_paths) { @@ -1793,9 +1965,9 @@ Py_INCREF(Py_None); } - if ((result = PyObject_CallFunction(receiver, - (char *)"OlsssO", - chpaths, rev, author, date, msg, + if ((result = PyObject_CallFunction(receiver, + (char *)"OlsssO", + chpaths, rev, author, date, msg, py_pool)) == NULL) { err = callback_exception_error(); @@ -1814,6 +1986,38 @@ return err; } +svn_error_t *svn_swig_py_info_receiver_func(void *baton, + const char *path, + const svn_info_t *info, + apr_pool_t *pool) +{ + PyObject *receiver = baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if ((receiver == NULL) || (receiver == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(receiver, + (char *)"sO&O&", + path, make_ob_info, info, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + Py_DECREF(result); + } + + svn_swig_py_release_py_lock(); + + return err; +} svn_error_t *svn_swig_py_client_blame_receiver_func(void *baton, apr_int64_t line_no, @@ -1826,16 +2030,16 @@ PyObject *receiver = baton; PyObject *result; svn_error_t *err = SVN_NO_ERROR; - + if ((receiver == NULL) || (receiver == Py_None)) return SVN_NO_ERROR; svn_swig_py_acquire_py_lock(); - if ((result = PyObject_CallFunction(receiver, + if ((result = PyObject_CallFunction(receiver, (char *) - (SVN_APR_INT64_T_PYCFMT "lsssO&"), - line_no, revision, author, date, line, + (SVN_APR_INT64_T_PYCFMT "lsssO&"), + line_no, revision, author, date, line, make_ob_pool, pool)) == NULL) { err = callback_exception_error(); @@ -1870,9 +2074,9 @@ svn_swig_py_acquire_py_lock(); - if ((result = PyObject_CallFunction(function, - (char *)"sslO&", - realm, username, may_save, + if ((result = PyObject_CallFunction(function, + (char *)"sslO&", + realm, username, may_save, make_ob_pool, pool)) == NULL) { err = callback_exception_error(); @@ -1882,7 +2086,7 @@ if (result != Py_None) { svn_auth_cred_simple_t *tmp_creds = NULL; - if (svn_swig_ConvertPtrString(result, (void **)&tmp_creds, + if (svn_swig_ConvertPtrString(result, (void **)&tmp_creds, "svn_auth_cred_simple_t *")) { err = type_conversion_error("svn_auth_cred_simple_t *"); @@ -1921,9 +2125,9 @@ svn_swig_py_acquire_py_lock(); - if ((result = PyObject_CallFunction(function, - (char *)"slO&", - realm, may_save, + if ((result = PyObject_CallFunction(function, + (char *)"slO&", + realm, may_save, make_ob_pool, pool)) == NULL) { err = callback_exception_error(); @@ -1933,7 +2137,7 @@ if (result != Py_None) { svn_auth_cred_username_t *tmp_creds = NULL; - if (svn_swig_ConvertPtrString(result, (void **)&tmp_creds, + if (svn_swig_ConvertPtrString(result, (void **)&tmp_creds, "svn_auth_cred_username_t *")) { err = type_conversion_error("svn_auth_cred_username_t *"); @@ -1974,7 +2178,7 @@ svn_swig_py_acquire_py_lock(); - if ((result = PyObject_CallFunction(function, (char *)"slO&lO&", + if ((result = PyObject_CallFunction(function, (char *)"slO&lO&", realm, failures, make_ob_auth_ssl_server_cert_info, cert_info, may_save, make_ob_pool, pool)) == NULL) { @@ -1986,7 +2190,7 @@ { svn_auth_cred_ssl_server_trust_t *tmp_creds = NULL; if (svn_swig_ConvertPtrString - (result, (void **)&tmp_creds, + (result, (void **)&tmp_creds, "svn_auth_cred_ssl_server_trust_t *")) { err = type_conversion_error @@ -2024,9 +2228,9 @@ svn_swig_py_acquire_py_lock(); - if ((result = PyObject_CallFunction(function, - (char *)"slO&", - realm, may_save, + if ((result = PyObject_CallFunction(function, + (char *)"slO&", + realm, may_save, make_ob_pool, pool)) == NULL) { err = callback_exception_error(); @@ -2037,7 +2241,7 @@ { svn_auth_cred_ssl_client_cert_t *tmp_creds = NULL; if (svn_swig_ConvertPtrString - (result, (void **)&tmp_creds, + (result, (void **)&tmp_creds, "svn_auth_cred_ssl_client_cert_t *")) { err = type_conversion_error("svn_auth_cred_ssl_client_cert_t *"); @@ -2075,9 +2279,9 @@ svn_swig_py_acquire_py_lock(); - if ((result = PyObject_CallFunction(function, - (char *)"slO&", - realm, may_save, + if ((result = PyObject_CallFunction(function, + (char *)"slO&", + realm, may_save, make_ob_pool, pool)) == NULL) { err = callback_exception_error(); @@ -2088,7 +2292,7 @@ { svn_auth_cred_ssl_client_cert_pw_t *tmp_creds = NULL; if (svn_swig_ConvertPtrString - (result, (void **)&tmp_creds, + (result, (void **)&tmp_creds, "svn_auth_cred_ssl_client_cert_pw_t *")) { err = type_conversion_error @@ -2108,3 +2312,377 @@ *cred = creds; return err; } + +/* svn_ra_callbacks_t */ +static svn_error_t * +ra_callbacks_open_tmp_file(apr_file_t **fp, + void *callback_baton, + apr_pool_t *pool) +{ + PyObject *callbacks = (PyObject *)callback_baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallMethod(callbacks, + "open_tmp_file", + (char *)"O&", + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else if (result == Py_None) + { + *fp = NULL; + } + else + { + *fp = svn_swig_py_make_file(result, pool); + if (*fp == NULL) + { + err = callback_exception_error(); + } + } + + Py_XDECREF(result); + svn_swig_py_release_py_lock(); + return err; +} + +void +svn_swig_py_setup_ra_callbacks(svn_ra_callbacks2_t **callbacks, + void **baton, + PyObject *py_callbacks, + apr_pool_t *pool) +{ + svn_error_t *err = svn_ra_create_callbacks(callbacks, pool); + PyObject *py_auth_baton; + + if (err) + { + svn_swig_py_svn_exception(err); + return; + } + + (*callbacks)->open_tmp_file = ra_callbacks_open_tmp_file; + + py_auth_baton = PyObject_GetAttrString(py_callbacks, "auth_baton"); + + if (svn_swig_ConvertPtrString(py_auth_baton, + (void **)&((*callbacks)->auth_baton), + "svn_auth_baton_t *")) + { + err = type_conversion_error("svn_auth_baton_t *"); + svn_swig_py_svn_exception(err); + Py_DECREF(py_auth_baton); + return; + } + + Py_XDECREF(py_auth_baton); + + *baton = py_callbacks; +} + +svn_error_t *svn_swig_py_commit_callback2(const svn_commit_info_t *commit_info, + void *baton, + apr_pool_t *pool) +{ + PyObject *receiver = baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if ((receiver == NULL) || (receiver == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(receiver, + (char *)"O&O&", + make_ob_commit_info, commit_info, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + Py_DECREF(result); + } + + svn_swig_py_release_py_lock(); + + return err; +} + +svn_error_t *svn_swig_py_commit_callback(svn_revnum_t new_revision, + const char *date, + const char *author, + void *baton) +{ + PyObject *receiver = baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if ((receiver == NULL) || (receiver == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(receiver, + (char *)"lss", + new_revision, date, author)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + Py_DECREF(result); + } + + svn_swig_py_release_py_lock(); + + return err; +} + +svn_error_t *svn_swig_py_ra_file_rev_handler_func( + void *baton, + const char *path, + svn_revnum_t rev, + apr_hash_t *rev_props, + svn_txdelta_window_handler_t *delta_handler, + void **delta_baton, + apr_array_header_t *prop_diffs, + apr_pool_t *pool) +{ + PyObject *handler = baton; + PyObject *result, *py_rev_props = NULL, *py_prop_diffs = NULL; + svn_error_t *err = SVN_NO_ERROR; + + if ((handler == NULL) || (handler == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + py_rev_props = svn_swig_py_prophash_to_dict(rev_props); + if (py_rev_props == NULL) + { + err = type_conversion_error("apr_hash_t *"); + goto error; + } + + py_prop_diffs = proparray_to_dict(prop_diffs); + + if (py_prop_diffs == NULL) + { + err = type_conversion_error("apr_array_header_t *"); + goto error; + } + + if ((result = PyObject_CallFunction(handler, + (char *)"slOOO&", + path, rev, py_rev_props, py_prop_diffs, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + + /* FIXME: Support returned TxDeltaWindow object and + * set delta_handler and delta_baton */ + *delta_handler = NULL; + *delta_baton = NULL; + + Py_XDECREF(result); + } + +error: + + Py_XDECREF(py_rev_props); + Py_XDECREF(py_prop_diffs); + + svn_swig_py_release_py_lock(); + + 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 +}; diff -Nur subversion-1.3.1/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c.orig subversion-1.3.1.new/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c.orig --- subversion-1.3.1/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c.orig 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c.orig 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,2634 @@ +/* + * swigutil_py.c: utility functions for the SWIG Python bindings + * + * ==================================================================== + * Copyright (c) 2000-2004 CollabNet. All rights reserved. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://subversion.tigris.org/license-1.html. + * If newer versions of this license are posted there, you may use a + * newer version instead, at your option. + * + * This software consists of voluntary contributions made by many + * individuals. For exact contribution history, see the revision + * history and logs, available at http://subversion.tigris.org/. + * ==================================================================== + */ + +/* Tell swigutil_py.h that we're inside the implementation */ +#define SVN_SWIG_SWIGUTIL_PY_C + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "svn_client.h" +#include "svn_string.h" +#include "svn_opt.h" +#include "svn_delta.h" +#include "svn_auth.h" +#include "svn_pools.h" + +#include "svn_private_config.h" /* for SVN_APR_INT64_T_PYCFMT */ + +#include "swig_python_external_runtime.swg" +#include "swigutil_py.h" + + + +/*** Manage the Global Interpreter Lock ***/ + +/* If both Python and APR have threads available, we can optimize ourselves + * by releasing the global interpreter lock when we drop into our SVN calls. + * + * In svn_types.i, svn_swig_py_release_py_lock is called before every + * function, then svn_swig_py_acquire_py_lock is called after every + * function. So, if these functions become no-ops, then Python will + * start to block... + * + * The Subversion libraries can be assumed to be thread-safe *only* when + * APR_HAS_THREAD is 1. The APR pool allocations aren't thread-safe unless + * APR_HAS_THREAD is 1. + */ + +#if defined(WITH_THREAD) && APR_HAS_THREADS +#define ACQUIRE_PYTHON_LOCK +#endif + +#ifdef ACQUIRE_PYTHON_LOCK +static apr_threadkey_t *_saved_thread_key = NULL; +static apr_pool_t *_saved_thread_pool = NULL; +#endif + +void svn_swig_py_release_py_lock(void) +{ +#ifdef ACQUIRE_PYTHON_LOCK + PyThreadState *thread_state; + + if (_saved_thread_key == NULL) + { + /* Obviously, creating a top-level pool for this is pretty stupid. */ + apr_pool_create(&_saved_thread_pool, NULL); + apr_threadkey_private_create(&_saved_thread_key, NULL, + _saved_thread_pool); + } + + thread_state = PyEval_SaveThread(); + apr_threadkey_private_set(thread_state, _saved_thread_key); +#endif +} + +void svn_swig_py_acquire_py_lock(void) +{ +#ifdef ACQUIRE_PYTHON_LOCK + void *val; + PyThreadState *thread_state; + apr_threadkey_private_get(&val, _saved_thread_key); + thread_state = val; + PyEval_RestoreThread(thread_state); +#endif +} + + + +/*** Automatic Pool Management Functions ***/ + +/* The application pool */ +static apr_pool_t *_global_pool = NULL; +static PyObject *_global_svn_swig_py_pool = NULL; +static char assertValid[] = "assert_valid"; +static char parentPool[] = "_parent_pool"; +static char addOwnedRef[] = "_add_owned_ref"; +static char removeOwnedRef[] = "_remove_owned_ref"; +static char wrap[] = "_wrap"; +static char unwrap[] = "_unwrap"; +static char setParentPool[] = "set_parent_pool"; +static char emptyTuple[] = "()"; +static char objectTuple[] = "(O)"; + + +apr_status_t svn_swig_py_initialize(void) +{ + apr_status_t status; + + if ((status = apr_initialize()) != APR_SUCCESS) + return status; + if (atexit(apr_terminate) != 0) + return APR_EGENERAL; + return APR_SUCCESS; +} + +/* Set the application pool */ +void svn_swig_py_set_application_pool(PyObject *py_pool, apr_pool_t *pool) +{ + _global_pool = pool; + _global_svn_swig_py_pool = py_pool; +} + +/* Clear the application pool */ +void svn_swig_py_clear_application_pool() +{ + _global_pool = NULL; + _global_svn_swig_py_pool = NULL; +} + +/* Get the application pool */ +void svn_swig_get_application_pool(PyObject **py_pool, apr_pool_t **pool) +{ + *pool = _global_pool; + *py_pool = _global_svn_swig_py_pool; +} + +/* Set the parent pool of a proxy object */ +static int proxy_set_pool(PyObject **proxy, PyObject *pool) +{ + PyObject *result; + + if (*proxy != NULL) + { + if (pool == NULL) + { + if (PyObject_HasAttrString(*proxy, setParentPool)) + { + result = PyObject_CallMethod(*proxy, setParentPool, emptyTuple); + if (result == NULL) + return 1; + Py_DECREF(result); + } + } + else + { + result = PyObject_CallMethod(pool, wrap, objectTuple, *proxy); + Py_DECREF(*proxy); + *proxy = result; + } + } + + return 0; +} + +/* Get the parent pool of a proxy object, or return the global application + * pool if one is not set. Returns a BORROWED reference! */ +static PyObject *proxy_get_pool(PyObject *proxy) +{ + PyObject *result; + if (PyObject_HasAttrString(proxy, parentPool)) + { + result = PyObject_GetAttrString(proxy, parentPool); + Py_DECREF(result); + } + else + { + result = _global_svn_swig_py_pool; + } + return result; +} + +/* Change an 'owned reference' allocated in a pool from oldRef to newRef. + * If oldRef is non-NULL and present in the parent pool of proxy, it is removed. + */ +int svn_swig_py_pool_set_owned_ref(PyObject *proxy, PyObject *oldRef, + PyObject *newRef) +{ + PyObject *temp; + PyObject *py_pool = proxy_get_pool(proxy); + + if (oldRef != NULL) + { + temp = PyObject_CallMethod(py_pool, removeOwnedRef, objectTuple, oldRef); + if (temp == NULL) + return 1; + else + Py_DECREF(temp); + } + if (newRef != NULL) + { + temp = PyObject_CallMethod(py_pool, addOwnedRef, objectTuple, newRef); + if (temp == NULL) + return 1; + else + Py_DECREF(temp); + } + return 0; +} + +/* Wrapper for SWIG_TypeQuery */ +#define svn_swig_TypeQuery(x) SWIG_TypeQuery(x) + +/** Wrapper for SWIG_NewPointerObj */ +PyObject *svn_swig_NewPointerObj(void *obj, swig_type_info *type, + PyObject *pool) +{ + PyObject *proxy = SWIG_NewPointerObj(obj, type, 0); + + if (proxy == NULL) + return NULL; + + if (proxy_set_pool(&proxy, pool)) + { + Py_DECREF(proxy); + return NULL; + } + + return proxy; +} + +/** svn_swig_NewPointerObj, except a string is used to describe the type */ +static PyObject *svn_swig_NewPointerObjString(void *ptr, const char *type, + PyObject *py_pool) +{ + swig_type_info *typeinfo = svn_swig_TypeQuery(type); + if (typeinfo == NULL) + { + PyErr_SetString(PyExc_TypeError, "Cannot find required typeobject"); + return NULL; + } + + /* ### cache the swig_type_info at some point? */ + return svn_swig_NewPointerObj(ptr, typeinfo, py_pool); +} + +/** Wrapper for SWIG_ConvertPtr */ +int svn_swig_ConvertPtr(PyObject *input, void **obj, swig_type_info *type) +{ + if (PyObject_HasAttrString(input, assertValid)) + { + PyObject *result = PyObject_CallMethod(input, assertValid, emptyTuple); + if (result == NULL) + return 1; + Py_DECREF(result); + } + if (PyObject_HasAttrString(input, unwrap)) + { + input = PyObject_CallMethod(input, unwrap, emptyTuple); + if (input == NULL) + return 1; + Py_DECREF(input); + } + + return SWIG_ConvertPtr(input, obj, type, SWIG_POINTER_EXCEPTION | 0); +} + +/** svn_swig_ConvertPtr, except a string is used to describe the type */ +static int svn_swig_ConvertPtrString(PyObject *input, + void **obj, const char *type) +{ + return svn_swig_ConvertPtr(input, obj, svn_swig_TypeQuery(type)); +} + +/** Wrapper for SWIG_MustGetPtr */ +void *svn_swig_MustGetPtr(void *input, swig_type_info *type, int argnum, + PyObject **py_pool) +{ + if (PyObject_HasAttrString(input, assertValid)) + { + PyObject *result = PyObject_CallMethod(input, assertValid, emptyTuple); + if (result == NULL) + return NULL; + Py_DECREF(result); + } + + if (py_pool != NULL) + *py_pool = proxy_get_pool((PyObject *) input); + + if (PyObject_HasAttrString(input, unwrap)) + { + input = PyObject_CallMethod(input, unwrap, emptyTuple); + if (input == NULL) + return NULL; + Py_DECREF((PyObject *) input); + } + + return SWIG_MustGetPtr(input, type, argnum, SWIG_POINTER_EXCEPTION | 0); +} + + +/*** Custom SubversionException stuffs. ***/ + +/* Global SubversionException class object. */ +static PyObject *SubversionException = NULL; + + +PyObject *svn_swig_py_exception_type(void) +{ + Py_INCREF(SubversionException); + return SubversionException; +} + +PyObject *svn_swig_py_register_exception(void) +{ + /* If we haven't created our exception class, do so. */ + if (SubversionException == NULL) + { + SubversionException = PyErr_NewException + ((char *)"libsvn._core.SubversionException", NULL, NULL); + } + + /* Regardless, return the exception class. */ + return svn_swig_py_exception_type(); +} + +void svn_swig_py_svn_exception(svn_error_t *err) +{ + PyObject *exc_ob, *apr_err_ob; + + if (err == NULL) + return; + + /* Make an integer for the error code. */ + apr_err_ob = PyInt_FromLong(err->apr_err); + if (apr_err_ob == NULL) + return; + + /* Instantiate a SubversionException object. */ + exc_ob = PyObject_CallFunction(SubversionException, (char *)"sO", + err->message, apr_err_ob); + if (exc_ob == NULL) + { + Py_DECREF(apr_err_ob); + return; + } + + /* Set the "apr_err" attribute of the exception to our error code. */ + if (PyObject_SetAttrString(exc_ob, (char *)"apr_err", apr_err_ob) == -1) + { + Py_DECREF(apr_err_ob); + Py_DECREF(exc_ob); + return; + } + + /* Finished with the apr_err object. */ + Py_DECREF(apr_err_ob); + + /* Set the error state to our exception object. */ + PyErr_SetObject(SubversionException, exc_ob); + + /* Finished with the exc_ob object. */ + Py_DECREF(exc_ob); +} + + + +/*** Helper/Conversion Routines ***/ + +/* Functions for making Python wrappers around Subversion structs */ +static PyObject *make_ob_pool(void *pool) +{ + /* Return a brand new default pool to Python. This pool isn't + * normally used for anything. It's just here for compatibility + * with Subversion 1.2. */ + apr_pool_t *new_pool = svn_pool_create(_global_pool); + PyObject *new_py_pool = svn_swig_NewPointerObj(new_pool, + svn_swig_TypeQuery("apr_pool_t *"), _global_svn_swig_py_pool); + (void) pool; /* Silence compiler warnings about unused parameter. */ + return new_py_pool; +} +static PyObject *make_ob_fs_root(svn_fs_root_t *ptr, PyObject *py_pool) +{ + return svn_swig_NewPointerObjString(ptr, "svn_fs_root_t *", py_pool); +} +/***/ + +/* Conversion from Python single objects (not hashes/lists/etc.) to + Subversion types. */ +static const char *make_string_from_ob(PyObject *ob, apr_pool_t *pool) +{ + if (ob == Py_None) + return NULL; + if (! PyString_Check(ob)) + { + PyErr_SetString(PyExc_TypeError, "not a string"); + return NULL; + } + return apr_pstrdup(pool, PyString_AS_STRING(ob)); +} +static svn_string_t *make_svn_string_from_ob(PyObject *ob, apr_pool_t *pool) +{ + if (ob == Py_None) + return NULL; + if (! PyString_Check(ob)) + { + PyErr_SetString(PyExc_TypeError, "not a string"); + return NULL; + } + return svn_string_create(PyString_AS_STRING(ob), pool); +} + + +/***/ + +static PyObject *convert_hash(apr_hash_t *hash, + PyObject * (*converter_func)(void *value, + void *ctx, + PyObject *py_pool), + void *ctx, PyObject *py_pool) +{ + apr_hash_index_t *hi; + PyObject *dict = PyDict_New(); + + if (dict == NULL) + return NULL; + + for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) + { + const void *key; + void *val; + PyObject *value; + + apr_hash_this(hi, &key, NULL, &val); + value = (*converter_func)(val, ctx, py_pool); + if (value == NULL) + { + Py_DECREF(dict); + return NULL; + } + /* ### gotta cast this thing cuz Python doesn't use "const" */ + if (PyDict_SetItemString(dict, (char *)key, value) == -1) + { + Py_DECREF(value); + Py_DECREF(dict); + return NULL; + } + Py_DECREF(value); + } + + return dict; +} + +static PyObject *convert_to_swigtype(void *value, void *ctx, PyObject *py_pool) +{ + /* ctx is a 'swig_type_info *' */ + return svn_swig_NewPointerObj(value, ctx, py_pool); +} + +static PyObject *convert_svn_string_t(void *value, void *ctx, + PyObject *py_pool) +{ + /* ctx is unused */ + + const svn_string_t *s = value; + + /* ### gotta cast this thing cuz Python doesn't use "const" */ + return PyString_FromStringAndSize((void *)s->data, s->len); +} + +static PyObject *convert_svn_client_commit_item_t(void *value, void *ctx) +{ + PyObject *list; + PyObject *path, *kind, *url, *rev, *cf_url, *state; + svn_client_commit_item_t *item = value; + + /* ctx is unused */ + + list = PyList_New(6); + + if (item->path) + path = PyString_FromString(item->path); + else + { + path = Py_None; + Py_INCREF(Py_None); + } + + if (item->url) + url = PyString_FromString(item->url); + else + { + url = Py_None; + Py_INCREF(Py_None); + } + + if (item->copyfrom_url) + cf_url = PyString_FromString(item->copyfrom_url); + else + { + cf_url = Py_None; + Py_INCREF(Py_None); + } + + kind = PyInt_FromLong(item->kind); + rev = PyInt_FromLong(item->revision); + state = PyInt_FromLong(item->state_flags); + + if (! (list && path && kind && url && rev && cf_url && state)) + { + Py_XDECREF(list); + Py_XDECREF(path); + Py_XDECREF(kind); + Py_XDECREF(url); + Py_XDECREF(rev); + Py_XDECREF(cf_url); + Py_XDECREF(state); + return NULL; + } + + PyList_SET_ITEM(list, 0, path); + PyList_SET_ITEM(list, 1, kind); + PyList_SET_ITEM(list, 2, url); + PyList_SET_ITEM(list, 3, rev); + PyList_SET_ITEM(list, 4, cf_url); + PyList_SET_ITEM(list, 5, state); + return list; +} + +PyObject *svn_swig_py_prophash_to_dict(apr_hash_t *hash) +{ + return convert_hash(hash, convert_svn_string_t, NULL, NULL); +} + +static PyObject *proparray_to_dict(const apr_array_header_t *array) +{ + PyObject *dict = PyDict_New(); + int i; + + if (dict == NULL) + return NULL; + + for (i = 0; i < array->nelts; ++i) + { + svn_prop_t prop; + PyObject *py_key, *py_value; + + prop = APR_ARRAY_IDX(array, i, svn_prop_t); + + py_key = PyString_FromString(prop.name); + if (py_key == NULL) + goto error; + + if (prop.value == NULL) + { + py_value = Py_None; + Py_INCREF(Py_None); + } + else + { + py_value = PyString_FromStringAndSize((void *)prop.value->data, + prop.value->len); + if (py_value == NULL) + { + Py_DECREF(py_key); + goto error; + } + } + + PyDict_SetItem(dict, py_key, py_value); + } + + return dict; + + error: + Py_DECREF(dict); + return NULL; + +} + + +PyObject *svn_swig_py_locationhash_to_dict(apr_hash_t *hash) +{ + /* Need special code for this because of the darned svn_revnum_t + keys. */ + apr_hash_index_t *hi; + PyObject *dict = PyDict_New(); + + if (dict == NULL) + return NULL; + + for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) + { + const void *k; + void *v; + PyObject *key, *value; + + apr_hash_this(hi, &k, NULL, &v); + key = PyLong_FromLong(*(svn_revnum_t *)k); + if (key == NULL) + { + Py_DECREF(dict); + return NULL; + } + value = PyString_FromString((char *)v); + if (value == NULL) + { + Py_DECREF(key); + Py_DECREF(dict); + return NULL; + } + if (PyDict_SetItem(dict, key, value) == -1) + { + Py_DECREF(value); + Py_DECREF(dict); + return NULL; + } + Py_DECREF(value); + Py_DECREF(key); + } + return dict; +} + +PyObject *svn_swig_py_convert_hash(apr_hash_t *hash, swig_type_info *type, + PyObject *py_pool) +{ + return convert_hash(hash, convert_to_swigtype, type, py_pool); +} + +#define DECLARE_SWIG_CONSTRUCTOR(type, dup) \ +static PyObject *make_ob_##type(void *value) \ +{ \ + apr_pool_t *new_pool = svn_pool_create(_global_pool); \ + PyObject *new_py_pool = svn_swig_NewPointerObj(new_pool, \ + svn_swig_TypeQuery("apr_pool_t *"), _global_svn_swig_py_pool); \ + svn_##type##_t *new_value = dup(value, new_pool); \ + return svn_swig_NewPointerObjString(new_value, "svn_" #type "_t *", \ + new_py_pool); \ +} + +DECLARE_SWIG_CONSTRUCTOR(txdelta_window, svn_txdelta_window_dup) +DECLARE_SWIG_CONSTRUCTOR(log_changed_path, svn_log_changed_path_dup) +DECLARE_SWIG_CONSTRUCTOR(wc_status, svn_wc_dup_status) +DECLARE_SWIG_CONSTRUCTOR(lock, svn_lock_dup) +DECLARE_SWIG_CONSTRUCTOR(auth_ssl_server_cert_info, + 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) +{ + return make_ob_log_changed_path(value); +} + +PyObject *svn_swig_py_c_strings_to_list(char **strings) +{ + PyObject *list = PyList_New(0); + char *s; + + while ((s = *strings++) != NULL) + { + PyObject *ob = PyString_FromString(s); + + if (ob == NULL) + goto error; + if (PyList_Append(list, ob) == -1) + goto error; + } + + return list; + + error: + Py_DECREF(list); + return NULL; +} + +apr_hash_t *svn_swig_py_stringhash_from_dict(PyObject *dict, + apr_pool_t *pool) +{ + apr_hash_t *hash; + PyObject *keys; + int i, num_keys; + + if (dict == Py_None) + return NULL; + + if (!PyDict_Check(dict)) + { + PyErr_SetString(PyExc_TypeError, "not a dictionary"); + return NULL; + } + + hash = apr_hash_make(pool); + keys = PyDict_Keys(dict); + num_keys = PyList_Size(keys); + for (i = 0; i < num_keys; i++) + { + PyObject *key = PyList_GetItem(keys, i); + PyObject *value = PyDict_GetItem(dict, key); + const char *propname = make_string_from_ob(key, pool); + const char *propval = make_string_from_ob(value, pool); + Py_DECREF(key); + Py_DECREF(value); + if (! (propname && propval)) + { + PyErr_SetString(PyExc_TypeError, + "dictionary keys/values aren't strings"); + Py_DECREF(keys); + return NULL; + } + apr_hash_set(hash, propname, APR_HASH_KEY_STRING, propval); + } + Py_DECREF(keys); + return hash; +} + + +apr_hash_t *svn_swig_py_prophash_from_dict(PyObject *dict, + apr_pool_t *pool) +{ + apr_hash_t *hash; + PyObject *keys; + int i, num_keys; + + if (dict == Py_None) + return NULL; + + if (!PyDict_Check(dict)) + { + PyErr_SetString(PyExc_TypeError, "not a dictionary"); + return NULL; + } + + hash = apr_hash_make(pool); + keys = PyDict_Keys(dict); + num_keys = PyList_Size(keys); + for (i = 0; i < num_keys; i++) + { + PyObject *key = PyList_GetItem(keys, i); + PyObject *value = PyDict_GetItem(dict, key); + const char *propname = make_string_from_ob(key, pool); + svn_string_t *propval = make_svn_string_from_ob(value, pool); + Py_DECREF(key); + Py_DECREF(value); + if (! (propname && propval)) + { + PyErr_SetString(PyExc_TypeError, + "dictionary keys/values aren't strings"); + Py_DECREF(keys); + return NULL; + } + apr_hash_set(hash, propname, APR_HASH_KEY_STRING, propval); + } + Py_DECREF(keys); + return hash; +} + + +const apr_array_header_t *svn_swig_py_strings_to_array(PyObject *source, + apr_pool_t *pool) +{ + int targlen; + apr_array_header_t *temp; + + if (!PySequence_Check(source)) + { + PyErr_SetString(PyExc_TypeError, "not a sequence"); + return NULL; + } + targlen = PySequence_Length(source); + temp = apr_array_make(pool, targlen, sizeof(const char *)); + /* APR_ARRAY_IDX doesn't actually increment the array item count + (like, say, apr_array_push would). */ + temp->nelts = targlen; + while (targlen--) + { + PyObject *o = PySequence_GetItem(source, targlen); + if (o == NULL) + return NULL; + if (!PyString_Check(o)) + { + Py_DECREF(o); + PyErr_SetString(PyExc_TypeError, "not a string"); + return NULL; + } + APR_ARRAY_IDX(temp, targlen, const char *) = PyString_AS_STRING(o); + Py_DECREF(o); + } + return temp; +} + + +const apr_array_header_t *svn_swig_py_revnums_to_array(PyObject *source, + apr_pool_t *pool) +{ + int targlen; + apr_array_header_t *temp; + + if (!PySequence_Check(source)) + { + PyErr_SetString(PyExc_TypeError, "not a sequence"); + return NULL; + } + targlen = PySequence_Length(source); + temp = apr_array_make(pool, targlen, sizeof(svn_revnum_t)); + /* APR_ARRAY_IDX doesn't actually increment the array item count + (like, say, apr_array_push would). */ + temp->nelts = targlen; + while (targlen--) + { + PyObject *o = PySequence_GetItem(source, targlen); + if (o == NULL) + return NULL; + if (PyLong_Check(o)) + { + APR_ARRAY_IDX(temp, targlen, svn_revnum_t) = + (svn_revnum_t)PyLong_AsLong(o); + } + else if (PyInt_Check(o)) + { + APR_ARRAY_IDX(temp, targlen, svn_revnum_t) = + (svn_revnum_t)PyInt_AsLong(o); + } + else + { + Py_DECREF(o); + PyErr_SetString(PyExc_TypeError, "not an integer type"); + return NULL; + } + Py_DECREF(o); + } + return temp; +} + + + +/*** apr_array_header_t conversions. To create a new type of + converter, simply copy-n-paste one of these function and tweak + the creation of the PyObject *ob. ***/ + +PyObject *svn_swig_py_array_to_list(const apr_array_header_t *array) +{ + PyObject *list = PyList_New(array->nelts); + int i; + + for (i = 0; i < array->nelts; ++i) + { + PyObject *ob = + PyString_FromString(APR_ARRAY_IDX(array, i, const char *)); + if (ob == NULL) + goto error; + PyList_SET_ITEM(list, i, ob); + } + return list; + + error: + Py_DECREF(list); + return NULL; +} + +/* Formerly used by pre-1.0 APIs. Now unused +PyObject *svn_swig_py_revarray_to_list(const apr_array_header_t *array) +{ + PyObject *list = PyList_New(array->nelts); + int i; + + for (i = 0; i < array->nelts; ++i) + { + PyObject *ob + = PyInt_FromLong(APR_ARRAY_IDX(array, i, svn_revnum_t)); + if (ob == NULL) + goto error; + PyList_SET_ITEM(list, i, ob); + } + return list; + + error: + Py_DECREF(list); + return NULL; +} +*/ + +static PyObject * +commit_item_array_to_list(const apr_array_header_t *array) +{ + PyObject *list = PyList_New(array->nelts); + int i; + + for (i = 0; i < array->nelts; ++i) + { + PyObject *ob = convert_svn_client_commit_item_t + (APR_ARRAY_IDX(array, i, svn_client_commit_item_t *), NULL); + if (ob == NULL) + goto error; + PyList_SET_ITEM(list, i, ob); + } + return list; + + error: + Py_DECREF(list); + return NULL; +} + + + +/*** Errors ***/ + +/* Return a Subversion error about a failed callback. */ +static svn_error_t *callback_exception_error(void) +{ + return svn_error_create(SVN_ERR_SWIG_PY_EXCEPTION_SET, NULL, + "Python callback raised an exception"); +} + +/* Raise a TypeError exception with MESSAGE, and return a Subversion + error about an invalid return from a callback. */ +static svn_error_t *callback_bad_return_error(const char *message) +{ + PyErr_SetString(PyExc_TypeError, message); + return svn_error_create(APR_EGENERAL, NULL, + "Python callback returned an invalid object"); +} + +/* Return a generic error about not being able to map types. */ +static svn_error_t *type_conversion_error(const char *datatype) +{ + return svn_error_createf(APR_EGENERAL, NULL, + "Error converting object of type '%s'", datatype); +} + + + +/*** Editor Wrapping ***/ + +/* this baton is used for the editor, directory, and file batons. */ +typedef struct { + PyObject *editor; /* the editor handling the callbacks */ + PyObject *baton; /* the dir/file baton (or NULL for edit baton) */ +} item_baton; + +static item_baton *make_baton(apr_pool_t *pool, + PyObject *editor, + PyObject *baton) +{ + item_baton *newb = apr_palloc(pool, sizeof(*newb)); + + /* Note: We steal the caller's reference to 'baton'. Also, to avoid + memory leaks, we borrow the caller's reference to 'editor'. In this + case, borrowing the reference to 'editor' is safe because the contents + of an item_baton struct are only used by functino calls which operate on + the editor itself. */ + newb->editor = editor; + newb->baton = baton; + + return newb; +} + +static svn_error_t *close_baton(void *baton, + const char *method) +{ + item_baton *ib = baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* If there is no baton object, then it is an edit_baton, and we should + not bother to pass an object. Note that we still shove a NULL onto + the stack, but the format specified just won't reference it. */ + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)method, + ib->baton ? (char *)"(O)" : NULL, + ib->baton)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* there is no return value, so just toss this object (probably Py_None) */ + Py_DECREF(result); + + /* We're now done with the baton. Since there isn't really a free, all + we need to do is note that its objects are no longer referenced by + the baton. */ + Py_XDECREF(ib->baton); + +#ifdef SVN_DEBUG + ib->editor = ib->baton = NULL; +#endif + + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *set_target_revision(void *edit_baton, + svn_revnum_t target_revision, + apr_pool_t *pool) +{ + item_baton *ib = edit_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"set_target_revision", + (char *)"l", target_revision)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* there is no return value, so just toss this object (probably Py_None) */ + Py_DECREF(result); + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *open_root(void *edit_baton, + svn_revnum_t base_revision, + apr_pool_t *dir_pool, + void **root_baton) +{ + item_baton *ib = edit_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"open_root", + (char *)"lO&", base_revision, + make_ob_pool, dir_pool)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* make_baton takes our 'result' reference */ + *root_baton = make_baton(dir_pool, ib->editor, result); + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *delete_entry(const char *path, + svn_revnum_t revision, + void *parent_baton, + apr_pool_t *pool) +{ + item_baton *ib = parent_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"delete_entry", + (char *)"slOO&", path, revision, ib->baton, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* there is no return value, so just toss this object (probably Py_None) */ + Py_DECREF(result); + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *add_directory(const char *path, + void *parent_baton, + const char *copyfrom_path, + svn_revnum_t copyfrom_revision, + apr_pool_t *dir_pool, + void **child_baton) +{ + item_baton *ib = parent_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"add_directory", + (char *)"sOslO&", path, ib->baton, + copyfrom_path, copyfrom_revision, + make_ob_pool, dir_pool)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* make_baton takes our 'result' reference */ + *child_baton = make_baton(dir_pool, ib->editor, result); + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *open_directory(const char *path, + void *parent_baton, + svn_revnum_t base_revision, + apr_pool_t *dir_pool, + void **child_baton) +{ + item_baton *ib = parent_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"open_directory", + (char *)"sOlO&", path, ib->baton, + base_revision, + make_ob_pool, dir_pool)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* make_baton takes our 'result' reference */ + *child_baton = make_baton(dir_pool, ib->editor, result); + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *change_dir_prop(void *dir_baton, + const char *name, + const svn_string_t *value, + apr_pool_t *pool) +{ + item_baton *ib = dir_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"change_dir_prop", + (char *)"Oss#O&", ib->baton, name, + value ? value->data : NULL, + value ? value->len : 0, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* there is no return value, so just toss this object (probably Py_None) */ + Py_DECREF(result); + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *close_directory(void *dir_baton, + apr_pool_t *pool) +{ + return close_baton(dir_baton, "close_directory"); +} + +static svn_error_t *add_file(const char *path, + void *parent_baton, + const char *copyfrom_path, + svn_revnum_t copyfrom_revision, + apr_pool_t *file_pool, + void **file_baton) +{ + item_baton *ib = parent_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"add_file", + (char *)"sOslO&", path, ib->baton, + copyfrom_path, copyfrom_revision, + make_ob_pool, file_pool)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* make_baton takes our 'result' reference */ + *file_baton = make_baton(file_pool, ib->editor, result); + + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *open_file(const char *path, + void *parent_baton, + svn_revnum_t base_revision, + apr_pool_t *file_pool, + void **file_baton) +{ + item_baton *ib = parent_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"open_file", + (char *)"sOlO&", path, ib->baton, + base_revision, + make_ob_pool, file_pool)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* make_baton takes our 'result' reference */ + *file_baton = make_baton(file_pool, ib->editor, result); + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *window_handler(svn_txdelta_window_t *window, + void *baton) +{ + PyObject *handler = baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + if (window == NULL) + { + /* the last call; it closes the handler */ + + /* invoke the handler with None for the window */ + /* ### python doesn't have 'const' on the format */ + result = PyObject_CallFunction(handler, (char *)"O", Py_None); + + /* we no longer need to refer to the handler object */ + Py_DECREF(handler); + } + else + { + /* invoke the handler with the window */ + /* ### python doesn't have 'const' on the format */ + result = PyObject_CallFunction(handler, (char *)"O&", + make_ob_txdelta_window, window); + } + + if (result == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* there is no return value, so just toss this object (probably Py_None) */ + Py_DECREF(result); + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *apply_textdelta(void *file_baton, + const char *base_checksum, + apr_pool_t *pool, + svn_txdelta_window_handler_t *handler, + void **h_baton) +{ + item_baton *ib = file_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"apply_textdelta", + (char *)"(Os)", ib->baton, + base_checksum)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* Interpret None to mean svn_delta_noop_window_handler. This is much + easier/faster than making code always have to write a NOOP handler + in Python. */ + if (result == Py_None) + { + Py_DECREF(result); + + *handler = svn_delta_noop_window_handler; + *h_baton = NULL; + } + else + { + /* return the thunk for invoking the handler. the baton takes our + 'result' reference, which is the handler. */ + *handler = window_handler; + *h_baton = result; + } + + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *change_file_prop(void *file_baton, + const char *name, + const svn_string_t *value, + apr_pool_t *pool) +{ + item_baton *ib = file_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"change_file_prop", + (char *)"Oss#O&", ib->baton, name, + value ? value->data : NULL, + value ? value->len : 0, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* there is no return value, so just toss this object (probably Py_None) */ + Py_DECREF(result); + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *close_file(void *file_baton, + const char *text_checksum, + apr_pool_t *pool) +{ + item_baton *ib = file_baton; + PyObject *result; + svn_error_t *err; + + svn_swig_py_acquire_py_lock(); + + /* ### python doesn't have 'const' on the method name and format */ + if ((result = PyObject_CallMethod(ib->editor, (char *)"close_file", + (char *)"(Os)", ib->baton, + text_checksum)) == NULL) + { + err = callback_exception_error(); + goto finished; + } + + /* there is no return value, so just toss this object (probably Py_None) */ + Py_DECREF(result); + + /* We're now done with the baton. Since there isn't really a free, all + we need to do is note that its objects are no longer referenced by + the baton. */ + Py_XDECREF(ib->baton); + +#ifdef SVN_DEBUG + ib->editor = ib->baton = NULL; +#endif + + err = SVN_NO_ERROR; + + finished: + svn_swig_py_release_py_lock(); + return err; +} + +static svn_error_t *close_edit(void *edit_baton, + apr_pool_t *pool) +{ + return close_baton(edit_baton, "close_edit"); +} + +static svn_error_t *abort_edit(void *edit_baton, + apr_pool_t *pool) +{ + return close_baton(edit_baton, "abort_edit"); +} + +void svn_swig_py_make_editor(const svn_delta_editor_t **editor, + void **edit_baton, + PyObject *py_editor, + apr_pool_t *pool) +{ + svn_delta_editor_t *thunk_editor = svn_delta_default_editor (pool); + + thunk_editor->set_target_revision = set_target_revision; + thunk_editor->open_root = open_root; + thunk_editor->delete_entry = delete_entry; + thunk_editor->add_directory = add_directory; + thunk_editor->open_directory = open_directory; + thunk_editor->change_dir_prop = change_dir_prop; + thunk_editor->close_directory = close_directory; + thunk_editor->add_file = add_file; + thunk_editor->open_file = open_file; + thunk_editor->apply_textdelta = apply_textdelta; + thunk_editor->change_file_prop = change_file_prop; + thunk_editor->close_file = close_file; + thunk_editor->close_edit = close_edit; + thunk_editor->abort_edit = abort_edit; + + *editor = thunk_editor; + *edit_baton = make_baton(pool, py_editor, NULL); +} + + + +/*** Other Wrappers for SVN Functions ***/ + + +apr_file_t *svn_swig_py_make_file (PyObject *py_file, + apr_pool_t *pool) +{ + apr_file_t *apr_file = NULL; + apr_status_t apr_err; + + if (py_file == NULL || py_file == Py_None) + return NULL; + + if (PyString_Check (py_file)) + { + /* input is a path -- just open an apr_file_t */ + char* fname = PyString_AS_STRING (py_file); + apr_err = apr_file_open (&apr_file, fname, + APR_CREATE | APR_READ | APR_WRITE, + APR_OS_DEFAULT, pool); + if (apr_err) + { + char buf[256]; + apr_strerror (apr_err, buf, sizeof(buf)); + PyErr_Format (PyExc_IOError, "apr_file_open failed: %s: '%s'", + buf, fname); + return NULL; + } + } + else if (PyFile_Check (py_file)) + { + FILE *file; + apr_os_file_t osfile; + + /* input is a file object -- convert to apr_file_t */ + file = PyFile_AsFile(py_file); +#ifdef WIN32 + osfile = (apr_os_file_t)_get_osfhandle(_fileno(file)); +#else + osfile = (apr_os_file_t)fileno(file); +#endif + apr_err = apr_os_file_put (&apr_file, &osfile, O_CREAT | O_WRONLY, pool); + if (apr_err) + { + char buf[256]; + apr_strerror (apr_err, buf, sizeof(buf)); + PyErr_Format (PyExc_IOError, "apr_os_file_put failed: %s", buf); + return NULL; + } + } + return apr_file; +} + + +static svn_error_t * +read_handler_pyio (void *baton, char *buffer, apr_size_t *len) +{ + PyObject *result; + PyObject *py_io = baton; + apr_size_t bytes; + svn_error_t *err = SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + if ((result = PyObject_CallMethod(py_io, (char *)"read", + (char *)"i", *len)) == NULL) + { + err = callback_exception_error(); + } + else if (PyString_Check(result)) + { + bytes = PyString_GET_SIZE(result); + if (bytes > *len) + { + err = callback_bad_return_error("Too many bytes"); + } + else + { + /* Writeback, in case this was a short read, indicating EOF */ + *len = bytes; + memcpy(buffer, PyString_AS_STRING(result), *len); + } + } + else + { + err = callback_bad_return_error("Not a string"); + } + Py_XDECREF(result); + svn_swig_py_release_py_lock(); + + return err; +} + +static svn_error_t * +write_handler_pyio (void *baton, const char *data, apr_size_t *len) +{ + PyObject *result; + PyObject *py_io = baton; + svn_error_t *err = SVN_NO_ERROR; + + if (data != NULL) + { + svn_swig_py_acquire_py_lock(); + if ((result = PyObject_CallMethod(py_io, (char *)"write", + (char *)"s#", data, *len)) == NULL) + { + err = callback_exception_error(); + } + Py_XDECREF(result); + svn_swig_py_release_py_lock(); + } + + return err; +} + +static svn_error_t * +close_handler_pyio(void *baton) +{ + PyObject *py_io = baton; + Py_DECREF(py_io); + return SVN_NO_ERROR; +} + + +svn_stream_t * +svn_swig_py_make_stream (PyObject *py_io, apr_pool_t *pool) +{ + svn_stream_t *stream; + + /* Borrow the caller's reference to py_io - this is safe only because the + * caller must have a reference in order to pass the object into the + * bindings, and we will be finished with the py_io object before we return + * to python. I.e. DO NOT STORE AWAY THE RESULTING svn_stream_t * for use + * over multiple calls into the bindings. */ + Py_INCREF(py_io); + stream = svn_stream_create (py_io, pool); + svn_stream_set_read (stream, read_handler_pyio); + svn_stream_set_write (stream, write_handler_pyio); + svn_stream_set_close (stream, close_handler_pyio); + + return stream; +} + + +void svn_swig_py_notify_func(void *baton, + const char *path, + svn_wc_notify_action_t action, + svn_node_kind_t kind, + const char *mime_type, + svn_wc_notify_state_t content_state, + svn_wc_notify_state_t prop_state, + svn_revnum_t revision) +{ + 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 *)"(siisiii)", + path, action, kind, + mime_type, + content_state, prop_state, + revision)) == 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_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) +{ + 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 *)"sO&", path, + make_ob_wc_status, status)) == 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(); +} + + +svn_error_t *svn_swig_py_cancel_func(void *cancel_baton) +{ + PyObject *function = cancel_baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if (function == NULL || function == Py_None) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + if ((result = PyObject_CallFunction(function, NULL)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (PyInt_Check(result)) + { + if (PyInt_AsLong(result)) + err = svn_error_create(SVN_ERR_CANCELLED, 0, NULL); + } + else if (PyLong_Check(result)) + { + if (PyLong_AsLong(result)) + err = svn_error_create(SVN_ERR_CANCELLED, 0, NULL); + } + else if (result != Py_None) + { + err = callback_bad_return_error("Not an integer or None"); + } + Py_DECREF(result); + } + svn_swig_py_release_py_lock(); + return err; +} + +svn_error_t *svn_swig_py_fs_get_locks_func (void *baton, + svn_lock_t *lock, + apr_pool_t *pool) +{ + PyObject *function = baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if (function == NULL || function == Py_None) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(function, (char *)"O&O&", + make_ob_lock, lock, + 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); + } + + svn_swig_py_release_py_lock(); + return err; +} + +svn_error_t *svn_swig_py_get_commit_log_func(const char **log_msg, + const char **tmp_file, + apr_array_header_t *commit_items, + void *baton, + apr_pool_t *pool) +{ + PyObject *function = baton; + PyObject *result; + PyObject *cmt_items; + svn_error_t *err; + + *log_msg = NULL; + *tmp_file = NULL; + + /* ### todo: for now, just ignore the whole tmp_file thing. */ + + if ((function == NULL) || (function == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if (commit_items) + { + cmt_items = commit_item_array_to_list(commit_items); + } + else + { + cmt_items = Py_None; + Py_INCREF(Py_None); + } + + if ((result = PyObject_CallFunction(function, + (char *)"OO&", + cmt_items, + make_ob_pool, pool)) == NULL) + { + Py_DECREF(cmt_items); + err = callback_exception_error(); + goto finished; + } + + Py_DECREF(cmt_items); + + if (result == Py_None) + { + Py_DECREF(result); + *log_msg = NULL; + err = SVN_NO_ERROR; + } + else if (PyString_Check(result)) + { + *log_msg = apr_pstrdup(pool, PyString_AS_STRING(result)); + Py_DECREF(result); + err = SVN_NO_ERROR; + } + else + { + Py_DECREF(result); + err = callback_bad_return_error("Not a string"); + } + + finished: + svn_swig_py_release_py_lock(); + return err; +} + + +svn_error_t *svn_swig_py_repos_authz_func(svn_boolean_t *allowed, + svn_fs_root_t *root, + const char *path, + void *baton, + apr_pool_t *pool) +{ + PyObject *function = baton; + PyObject *result; + PyObject *py_pool, *py_root; + svn_error_t *err = SVN_NO_ERROR; + + *allowed = TRUE; + + if (function == NULL || function == Py_None) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + py_pool = make_ob_pool(pool); + if (py_pool == NULL) + { + err = callback_exception_error(); + goto finished; + } + py_root = make_ob_fs_root(root, py_pool); + if (py_root == NULL) + { + Py_DECREF(py_pool); + err = callback_exception_error(); + goto finished; + } + + if ((result = PyObject_CallFunction(function, + (char *)"OsO", + py_root, path, py_pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (PyInt_Check(result)) + *allowed = PyInt_AsLong(result); + else if (PyLong_Check(result)) + *allowed = PyLong_AsLong(result); + else + err = callback_bad_return_error("Not an integer"); + Py_DECREF(result); + } + Py_DECREF(py_root); + Py_DECREF(py_pool); +finished: + svn_swig_py_release_py_lock(); + return err; +} + + +svn_error_t *svn_swig_py_repos_history_func(void *baton, + const char *path, + svn_revnum_t revision, + apr_pool_t *pool) +{ + PyObject *function = baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if (function == NULL || function == Py_None) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + if ((result = PyObject_CallFunction(function, + (char *)"slO&", + path, revision, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + Py_DECREF(result); + } + svn_swig_py_release_py_lock(); + return err; +} + + +svn_error_t *svn_swig_py_log_receiver(void *baton, + apr_hash_t *changed_paths, + svn_revnum_t rev, + const char *author, + const char *date, + const char *msg, + apr_pool_t *pool) +{ + PyObject *receiver = baton; + PyObject *result, *py_pool; + PyObject *chpaths; + svn_error_t *err = SVN_NO_ERROR; + + if ((receiver == NULL) || (receiver == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + py_pool = make_ob_pool(pool); + if (py_pool == NULL) + { + err = callback_exception_error(); + goto finished; + } + + if (changed_paths) + { + chpaths = convert_hash(changed_paths, convert_log_changed_path, + NULL, NULL); + } + else + { + chpaths = Py_None; + Py_INCREF(Py_None); + } + + if ((result = PyObject_CallFunction(receiver, + (char *)"OlsssO", + chpaths, rev, author, date, msg, + py_pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + Py_DECREF(result); + } + + Py_DECREF(chpaths); + Py_DECREF(py_pool); +finished: + svn_swig_py_release_py_lock(); + return err; +} + +svn_error_t *svn_swig_py_info_receiver_func(void *baton, + const char *path, + const svn_info_t *info, + apr_pool_t *pool) +{ + PyObject *receiver = baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if ((receiver == NULL) || (receiver == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(receiver, + (char *)"sO&O&", + path, make_ob_info, info, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + Py_DECREF(result); + } + + svn_swig_py_release_py_lock(); + + return err; +} + +svn_error_t *svn_swig_py_client_blame_receiver_func(void *baton, + apr_int64_t line_no, + svn_revnum_t revision, + const char *author, + const char *date, + const char *line, + apr_pool_t *pool) +{ + PyObject *receiver = baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if ((receiver == NULL) || (receiver == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(receiver, + (char *) + (SVN_APR_INT64_T_PYCFMT "lsssO&"), + line_no, revision, author, date, line, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + Py_DECREF(result); + } + + svn_swig_py_release_py_lock(); + return err; +} + + +svn_error_t * +svn_swig_py_auth_simple_prompt_func (svn_auth_cred_simple_t **cred, + void *baton, + const char *realm, + const char *username, + svn_boolean_t may_save, + apr_pool_t *pool) +{ + PyObject *function = baton; + PyObject *result; + svn_auth_cred_simple_t *creds = NULL; + svn_error_t *err = SVN_NO_ERROR; + + if ((function == NULL) || (function == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(function, + (char *)"sslO&", + realm, username, may_save, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + { + svn_auth_cred_simple_t *tmp_creds = NULL; + if (svn_swig_ConvertPtrString(result, (void **)&tmp_creds, + "svn_auth_cred_simple_t *")) + { + err = type_conversion_error("svn_auth_cred_simple_t *"); + } + else + { + creds = apr_pcalloc(pool, sizeof (*creds)); + creds->username = tmp_creds->username ? \ + apr_pstrdup(pool, tmp_creds->username) : NULL; + creds->password = tmp_creds->password ? \ + apr_pstrdup(pool, tmp_creds->password) : NULL; + creds->may_save = tmp_creds->may_save; + } + } + Py_DECREF(result); + } + svn_swig_py_release_py_lock(); + *cred = creds; + return err; +} + +svn_error_t * +svn_swig_py_auth_username_prompt_func (svn_auth_cred_username_t **cred, + void *baton, + const char *realm, + svn_boolean_t may_save, + apr_pool_t *pool) +{ + PyObject *function = baton; + PyObject *result; + svn_auth_cred_username_t *creds = NULL; + svn_error_t *err = SVN_NO_ERROR; + + if ((function == NULL) || (function == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(function, + (char *)"slO&", + realm, may_save, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + { + svn_auth_cred_username_t *tmp_creds = NULL; + if (svn_swig_ConvertPtrString(result, (void **)&tmp_creds, + "svn_auth_cred_username_t *")) + { + err = type_conversion_error("svn_auth_cred_username_t *"); + } + else + { + creds = apr_pcalloc(pool, sizeof (*creds)); + creds->username = tmp_creds->username ? \ + apr_pstrdup(pool, tmp_creds->username) : NULL; + creds->may_save = tmp_creds->may_save; + } + } + Py_DECREF(result); + } + svn_swig_py_release_py_lock(); + *cred = creds; + return err; +} + + +svn_error_t * +svn_swig_py_auth_ssl_server_trust_prompt_func( + svn_auth_cred_ssl_server_trust_t **cred, + void *baton, + const char *realm, + apr_uint32_t failures, + const svn_auth_ssl_server_cert_info_t *cert_info, + svn_boolean_t may_save, + apr_pool_t *pool) +{ + PyObject *function = baton; + PyObject *result; + svn_auth_cred_ssl_server_trust_t *creds = NULL; + svn_error_t *err = SVN_NO_ERROR; + + if ((function == NULL) || (function == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(function, (char *)"slO&lO&", + realm, failures, make_ob_auth_ssl_server_cert_info, + cert_info, may_save, make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + { + svn_auth_cred_ssl_server_trust_t *tmp_creds = NULL; + if (svn_swig_ConvertPtrString + (result, (void **)&tmp_creds, + "svn_auth_cred_ssl_server_trust_t *")) + { + err = type_conversion_error + ("svn_auth_cred_ssl_server_trust_t *"); + } + else + { + creds = apr_pcalloc(pool, sizeof (*creds)); + *creds = *tmp_creds; + } + } + Py_DECREF(result); + } + + svn_swig_py_release_py_lock(); + *cred = creds; + return err; +} + +svn_error_t * +svn_swig_py_auth_ssl_client_cert_prompt_func( + svn_auth_cred_ssl_client_cert_t **cred, + void *baton, + const char *realm, + svn_boolean_t may_save, + apr_pool_t *pool) +{ + PyObject *function = baton; + PyObject *result; + svn_auth_cred_ssl_client_cert_t *creds = NULL; + svn_error_t *err = SVN_NO_ERROR; + + if ((function == NULL) || (function == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(function, + (char *)"slO&", + realm, may_save, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + { + svn_auth_cred_ssl_client_cert_t *tmp_creds = NULL; + if (svn_swig_ConvertPtrString + (result, (void **)&tmp_creds, + "svn_auth_cred_ssl_client_cert_t *")) + { + err = type_conversion_error("svn_auth_cred_ssl_client_cert_t *"); + } + else + { + creds = apr_pcalloc(pool, sizeof (*creds)); + creds->cert_file = tmp_creds->cert_file ? \ + apr_pstrdup(pool, tmp_creds->cert_file) : NULL; + creds->may_save = tmp_creds->may_save; + } + } + Py_DECREF(result); + } + svn_swig_py_release_py_lock(); + *cred = creds; + return err; +} + +svn_error_t * +svn_swig_py_auth_ssl_client_cert_pw_prompt_func( + svn_auth_cred_ssl_client_cert_pw_t **cred, + void *baton, + const char *realm, + svn_boolean_t may_save, + apr_pool_t *pool) +{ + PyObject *function = baton; + PyObject *result; + svn_auth_cred_ssl_client_cert_pw_t *creds = NULL; + svn_error_t *err = SVN_NO_ERROR; + + if ((function == NULL) || (function == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(function, + (char *)"slO&", + realm, may_save, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + { + svn_auth_cred_ssl_client_cert_pw_t *tmp_creds = NULL; + if (svn_swig_ConvertPtrString + (result, (void **)&tmp_creds, + "svn_auth_cred_ssl_client_cert_pw_t *")) + { + err = type_conversion_error + ("svn_auth_cred_ssl_client_cert_pw_t *"); + } + else + { + creds = apr_pcalloc(pool, sizeof (*creds)); + creds->password = tmp_creds->password ? \ + apr_pstrdup(pool, tmp_creds->password) : NULL; + creds->may_save = tmp_creds->may_save; + } + } + Py_DECREF(result); + } + svn_swig_py_release_py_lock(); + *cred = creds; + return err; +} + +void +svn_swig_py_setup_ra_callbacks(svn_ra_callbacks2_t **callbacks, + void **baton, + PyObject *py_callbacks, + apr_pool_t *pool) +{ + svn_error_t *err = svn_ra_create_callbacks(callbacks, pool); + + if (err) + { + svn_swig_py_svn_exception(err); + return; + } + + *baton = py_callbacks; +} + +svn_error_t *svn_swig_py_commit_callback2(const svn_commit_info_t *commit_info, + void *baton, + apr_pool_t *pool) +{ + PyObject *receiver = baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if ((receiver == NULL) || (receiver == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(receiver, + (char *)"O&O&", + make_ob_commit_info, commit_info, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + Py_DECREF(result); + } + + svn_swig_py_release_py_lock(); + + return err; +} + +svn_error_t *svn_swig_py_commit_callback(svn_revnum_t new_revision, + const char *date, + const char *author, + void *baton) +{ + PyObject *receiver = baton; + PyObject *result; + svn_error_t *err = SVN_NO_ERROR; + + if ((receiver == NULL) || (receiver == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + if ((result = PyObject_CallFunction(receiver, + (char *)"lss", + new_revision, date, author)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + Py_DECREF(result); + } + + svn_swig_py_release_py_lock(); + + return err; +} + +svn_error_t *svn_swig_py_ra_file_rev_handler_func( + void *baton, + const char *path, + svn_revnum_t rev, + apr_hash_t *rev_props, + svn_txdelta_window_handler_t *delta_handler, + void **delta_baton, + apr_array_header_t *prop_diffs, + apr_pool_t *pool) +{ + PyObject *handler = baton; + PyObject *result, *py_rev_props = NULL, *py_prop_diffs = NULL; + svn_error_t *err = SVN_NO_ERROR; + + if ((handler == NULL) || (handler == Py_None)) + return SVN_NO_ERROR; + + svn_swig_py_acquire_py_lock(); + + py_rev_props = svn_swig_py_prophash_to_dict(rev_props); + if (py_rev_props == NULL) + { + err = type_conversion_error("apr_hash_t *"); + goto error; + } + + py_prop_diffs = proparray_to_dict(prop_diffs); + + if (py_prop_diffs == NULL) + { + err = type_conversion_error("apr_array_header_t *"); + goto error; + } + + if ((result = PyObject_CallFunction(handler, + (char *)"slOOO&", + path, rev, py_rev_props, py_prop_diffs, + make_ob_pool, pool)) == NULL) + { + err = callback_exception_error(); + } + else + { + if (result != Py_None) + err = callback_bad_return_error("Not None"); + + /* FIXME: Support returned TxDeltaWindow object and + * set delta_handler and delta_baton */ + *delta_handler = NULL; + *delta_baton = NULL; + + Py_XDECREF(result); + } + +error: + + Py_XDECREF(py_rev_props); + Py_XDECREF(py_prop_diffs); + + svn_swig_py_release_py_lock(); + + 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 +}; diff -Nur subversion-1.3.1/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c.rej subversion-1.3.1.new/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c.rej --- subversion-1.3.1/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c.rej 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c.rej 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,46 @@ +*************** +*** 1569,1587 **** + return err; + } + + svn_stream_t * + svn_swig_py_make_stream(PyObject *py_io, apr_pool_t *pool) + { + svn_stream_t *stream; + +- /* Borrow the caller's reference to py_io - this is safe only because the +- * caller must have a reference in order to pass the object into the +- * bindings, and we will be finished with the py_io object before we return +- * to python. I.e. DO NOT STORE AWAY THE RESULTING svn_stream_t * for use +- * over multiple calls into the bindings. */ + stream = svn_stream_create(py_io, pool); + svn_stream_set_read(stream, read_handler_pyio); + svn_stream_set_write(stream, write_handler_pyio); + + return stream; + } +--- 1569,1592 ---- + return err; + } + ++ static svn_error_t * ++ close_handler_pyio(void *baton) ++ { ++ PyObject *py_io = baton; ++ Py_DECREF(py_io); ++ return SVN_NO_ERROR; ++ } ++ + svn_stream_t * + svn_swig_py_make_stream(PyObject *py_io, apr_pool_t *pool) + { + svn_stream_t *stream; + ++ Py_INCREF(py_io); + stream = svn_stream_create(py_io, pool); + svn_stream_set_read(stream, read_handler_pyio); + svn_stream_set_write(stream, write_handler_pyio); ++ svn_stream_set_close(stream, close_handler_pyio); + + return stream; + } diff -Nur subversion-1.3.1/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h subversion-1.3.1.new/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h --- subversion-1.3.1/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h 2005-10-20 23:17:19.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h 2006-07-05 01:04:06.000000000 +0100 @@ -79,6 +79,9 @@ SVN_SWIG_SWIGUTIL_EXPORT void svn_swig_get_application_pool(PyObject **py_pool, apr_pool_t **pool); +/* Set a Python 'owned' reference on the pool of the given proxy object */ +int svn_swig_py_pool_set_owned_ref(PyObject *proxy, PyObject *oldRef, PyObject *newRef); + /*** SWIG Wrappers ***/ @@ -198,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 @@ -249,6 +257,13 @@ const char *msg, apr_pool_t *pool); +/* thunked info receiver function */ +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_info_receiver_func(void *py_receiver, + const char *path, + const svn_info_t *info, + apr_pool_t *pool); + /* thunked blame receiver function */ SVN_SWIG_SWIGUTIL_EXPORT svn_error_t *svn_swig_py_client_blame_receiver_func(void *baton, @@ -303,6 +318,45 @@ svn_boolean_t may_save, apr_pool_t *pool); +SVN_SWIG_SWIGUTIL_EXPORT +void +svn_swig_py_setup_ra_callbacks(svn_ra_callbacks2_t **callbacks, + void **baton, + PyObject *py_callbacks, + apr_pool_t *pool); +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_commit_callback2(const svn_commit_info_t *commit_info, + void *baton, + apr_pool_t *pool); + +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_commit_callback(svn_revnum_t new_revision, + const char *date, + const char *author, + void *baton); + + +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_ra_file_rev_handler_func( + void *baton, + const char *path, + svn_revnum_t rev, + apr_hash_t *rev_props, + svn_txdelta_window_handler_t *delta_handler, + void **delta_baton, + apr_array_header_t *prop_diffs, + apr_pool_t *pool); + +SVN_SWIG_SWIGUTIL_EXPORT +extern const svn_ra_reporter2_t swig_py_ra_reporter2; + +SVN_SWIG_SWIGUTIL_EXPORT +void +svn_swig_py_setup_ra_callbacks(svn_ra_callbacks2_t **callbacks, + void **baton, + PyObject *py_callbacks, + apr_pool_t *pool); + #ifdef __cplusplus } #endif /* __cplusplus */ diff -Nur subversion-1.3.1/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h.orig subversion-1.3.1.new/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h.orig --- subversion-1.3.1/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h.orig 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h.orig 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,357 @@ +/* + * swigutil_py.h : utility functions and stuff for the SWIG Python bindings + * + * ==================================================================== + * Copyright (c) 2000-2004 CollabNet. All rights reserved. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://subversion.tigris.org/license-1.html. + * If newer versions of this license are posted there, you may use a + * newer version instead, at your option. + * + * This software consists of voluntary contributions made by many + * individuals. For exact contribution history, see the revision + * history and logs, available at http://subversion.tigris.org/. + * ==================================================================== + */ + + +#ifndef SVN_SWIG_SWIGUTIL_PY_H +#define SVN_SWIG_SWIGUTIL_PY_H + +#include + +#include +#include +#include +#include +#include + +#include "svn_types.h" +#include "svn_string.h" +#include "svn_delta.h" +#include "svn_client.h" +#include "svn_repos.h" + +/* Define DLL export magic on Windows. */ +#ifdef WIN32 +# ifdef SVN_SWIG_SWIGUTIL_PY_C +# define SVN_SWIG_SWIGUTIL_EXPORT __declspec(dllexport) +# else +# define SVN_SWIG_SWIGUTIL_EXPORT __declspec(dllimport) +# endif +#else +# define SVN_SWIG_SWIGUTIL_EXPORT +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +/* Initialize the libsvn_swig_py library. */ +SVN_SWIG_SWIGUTIL_EXPORT +apr_status_t svn_swig_py_initialize(void); + + + +/* Functions to manage python's global interpreter lock */ +SVN_SWIG_SWIGUTIL_EXPORT +void svn_swig_py_release_py_lock(void); + +SVN_SWIG_SWIGUTIL_EXPORT +void svn_swig_py_acquire_py_lock(void); + + +/*** Automatic Pool Management Functions ***/ + +/* Set the application pool */ +SVN_SWIG_SWIGUTIL_EXPORT +void svn_swig_py_set_application_pool(PyObject *py_pool, apr_pool_t *pool); + +/* Clear the application pool */ +SVN_SWIG_SWIGUTIL_EXPORT +void svn_swig_py_clear_application_pool(void); + +/* Get the application pool */ +SVN_SWIG_SWIGUTIL_EXPORT +void svn_swig_get_application_pool(PyObject **py_pool, apr_pool_t **pool); + +/* Set a Python 'owned' reference on the pool of the given proxy object */ +int svn_swig_py_pool_set_owned_ref(PyObject *proxy, PyObject *oldRef, PyObject *newRef); + + +/*** SWIG Wrappers ***/ + +/* Wrapper for SWIG_NewPointerObj */ +SVN_SWIG_SWIGUTIL_EXPORT +PyObject *svn_swig_NewPointerObj(void *obj, swig_type_info *type, + PyObject *pool); + +/* Wrapper for SWIG_ConvertPtr */ +SVN_SWIG_SWIGUTIL_EXPORT +int svn_swig_ConvertPtr(PyObject *input, void **obj, swig_type_info *type); + +/* Wrapper for SWIG_MustGetPtr */ +SVN_SWIG_SWIGUTIL_EXPORT +void *svn_swig_MustGetPtr(void *input, swig_type_info *type, int argnum, + PyObject **py_pool); + +/*** Functions to expose a custom SubversionException ***/ + +/* register a new subversion exception class */ +SVN_SWIG_SWIGUTIL_EXPORT +PyObject *svn_swig_py_register_exception(void); + +/* get the object which represents the subversion exception class */ +SVN_SWIG_SWIGUTIL_EXPORT +PyObject *svn_swig_py_exception_type(void); + +/* raise a subversion exception, created from a normal subversion error */ +SVN_SWIG_SWIGUTIL_EXPORT +void svn_swig_py_svn_exception(svn_error_t *err); + + + +/* helper function to convert an apr_hash_t* (char* -> svnstring_t*) to + a Python dict */ +SVN_SWIG_SWIGUTIL_EXPORT +PyObject *svn_swig_py_prophash_to_dict(apr_hash_t *hash); + +/* helper function to convert an apr_hash_t* (svn_revnum_t* -> const + char *) to a Python dict */ +SVN_SWIG_SWIGUTIL_EXPORT +PyObject *svn_swig_py_locationhash_to_dict(apr_hash_t *hash); + +/* convert a hash of 'const char *' -> TYPE into a Python dict */ +SVN_SWIG_SWIGUTIL_EXPORT +PyObject *svn_swig_py_convert_hash(apr_hash_t *hash, swig_type_info *type, + PyObject *py_pool); + +/* helper function to convert a 'char **' into a Python list of string + objects */ +SVN_SWIG_SWIGUTIL_EXPORT +PyObject *svn_swig_py_c_strings_to_list(char **strings); + +/* helper function to convert an array of 'const char *' to a Python list + of string objects */ +SVN_SWIG_SWIGUTIL_EXPORT +PyObject *svn_swig_py_array_to_list(const apr_array_header_t *strings); + +/* helper function to convert an array of 'svn_revnum_t' to a Python list + of int objects */ +/* Formerly used by pre-1.0 APIs. Now unused +PyObject *svn_swig_py_revarray_to_list(const apr_array_header_t *revs); +*/ + +/* helper function to convert a Python dictionary mapping strings to + strings into an apr_hash_t mapping const char *'s to const char *'s, + allocated in POOL. */ +SVN_SWIG_SWIGUTIL_EXPORT +apr_hash_t *svn_swig_py_stringhash_from_dict(PyObject *dict, + apr_pool_t *pool); + +/* helper function to convert a Python dictionary mapping strings to + strings into an apr_hash_t mapping const char *'s to svn_string_t's, + allocated in POOL. */ +SVN_SWIG_SWIGUTIL_EXPORT +apr_hash_t *svn_swig_py_prophash_from_dict(PyObject *dict, + apr_pool_t *pool); + +/* helper function to convert a Python sequence of strings into an + 'apr_array_header_t *' of 'const char *' objects. Note that the + objects must remain alive -- the values are not copied. This is + appropriate for incoming arguments which are defined to last the + duration of the function's execution. */ +SVN_SWIG_SWIGUTIL_EXPORT +const apr_array_header_t *svn_swig_py_strings_to_array(PyObject *source, + apr_pool_t *pool); + +/* like svn_swig_py_strings_to_array(), but for array's of 'svn_revnum_t's. */ +SVN_SWIG_SWIGUTIL_EXPORT +const apr_array_header_t *svn_swig_py_revnums_to_array(PyObject *source, + apr_pool_t *pool); + +/* make an editor that "thunks" from C callbacks up to Python */ +SVN_SWIG_SWIGUTIL_EXPORT +void svn_swig_py_make_editor(const svn_delta_editor_t **editor, + void **edit_baton, + PyObject *py_editor, + apr_pool_t *pool); + +SVN_SWIG_SWIGUTIL_EXPORT +apr_file_t *svn_swig_py_make_file(PyObject *py_file, + apr_pool_t *pool); + +SVN_SWIG_SWIGUTIL_EXPORT +svn_stream_t *svn_swig_py_make_stream(PyObject *py_io, + apr_pool_t *pool); + +/* a notify function that executes a Python function that is passed in + via the baton argument */ +SVN_SWIG_SWIGUTIL_EXPORT +void svn_swig_py_notify_func(void *baton, + const char *path, + svn_wc_notify_action_t action, + svn_node_kind_t kind, + const char *mime_type, + svn_wc_notify_state_t content_state, + 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 +void svn_swig_py_status_func(void *baton, + const char *path, + svn_wc_status_t *status); + +/* a cancel function that executes a Python function passed in via the + cancel_baton argument. */ +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_cancel_func(void *cancel_baton); + +/* thunked fs get_locks function */ +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_fs_get_locks_func (void *baton, + svn_lock_t *lock, + apr_pool_t *pool); + +/* thunked commit log fetcher */ +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_get_commit_log_func(const char **log_msg, + const char **tmp_file, + apr_array_header_t *commit_items, + void *baton, + apr_pool_t *pool); + +/* thunked repos authz callback function */ +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_repos_authz_func(svn_boolean_t *allowed, + svn_fs_root_t *root, + const char *path, + void *baton, + apr_pool_t *pool); + +/* thunked history callback function */ +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_repos_history_func(void *baton, + const char *path, + svn_revnum_t revision, + apr_pool_t *pool); + +/* thunked log receiver function */ +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_log_receiver(void *py_receiver, + apr_hash_t *changed_paths, + svn_revnum_t rev, + const char *author, + const char *date, + const char *msg, + apr_pool_t *pool); + +/* thunked info receiver function */ +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_info_receiver_func(void *py_receiver, + const char *path, + const svn_info_t *info, + apr_pool_t *pool); + +/* thunked blame receiver function */ +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_client_blame_receiver_func(void *baton, + apr_int64_t line_no, + svn_revnum_t revision, + const char *author, + const char *date, + const char *line, + apr_pool_t *pool); + +/* auth provider callbacks */ +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_auth_simple_prompt_func( + svn_auth_cred_simple_t **cred, + void *baton, + const char *realm, + const char *username, + svn_boolean_t may_save, + apr_pool_t *pool); + +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_auth_username_prompt_func( + svn_auth_cred_username_t **cred, + void *baton, + const char *realm, + svn_boolean_t may_save, + apr_pool_t *pool); + +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_auth_ssl_server_trust_prompt_func( + svn_auth_cred_ssl_server_trust_t **cred, + void *baton, + const char *realm, + apr_uint32_t failures, + const svn_auth_ssl_server_cert_info_t *cert_info, + svn_boolean_t may_save, + apr_pool_t *pool); + +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_auth_ssl_client_cert_prompt_func( + svn_auth_cred_ssl_client_cert_t **cred, + void *baton, + const char *realm, + svn_boolean_t may_save, + apr_pool_t *pool); + +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_auth_ssl_client_cert_pw_prompt_func( + svn_auth_cred_ssl_client_cert_pw_t **cred, + void *baton, + const char *realm, + svn_boolean_t may_save, + apr_pool_t *pool); + +SVN_SWIG_SWIGUTIL_EXPORT +void +svn_swig_py_setup_ra_callbacks(svn_ra_callbacks2_t **callbacks, + void **baton, + PyObject *py_callbacks, + apr_pool_t *pool); +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_commit_callback2(const svn_commit_info_t *commit_info, + void *baton, + apr_pool_t *pool); + +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_commit_callback(svn_revnum_t new_revision, + const char *date, + const char *author, + void *baton); + + +SVN_SWIG_SWIGUTIL_EXPORT +svn_error_t *svn_swig_py_ra_file_rev_handler_func( + void *baton, + const char *path, + svn_revnum_t rev, + apr_hash_t *rev_props, + svn_txdelta_window_handler_t *delta_handler, + void **delta_baton, + 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 */ + +#endif /* SVN_SWIG_SWIGUTIL_PY_H */ diff -Nur subversion-1.3.1/subversion/bindings/swig/python/tests/client.py subversion-1.3.1.new/subversion/bindings/swig/python/tests/client.py --- subversion-1.3.1/subversion/bindings/swig/python/tests/client.py 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/python/tests/client.py 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,111 @@ +import unittest, os, tempfile, types + +from svn import core, repos, fs, delta, client, wc + +from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \ + REPOS_PATH +from urllib import pathname2url + +class SubversionRepositoryTestCase(unittest.TestCase): + """Test cases for the Subversion repository layer""" + + def setUp(self): + """Load a Subversion repository""" + self.client_ctx = client.svn_client_create_context() + + providers = [ + client.svn_client_get_simple_provider(), + client.svn_client_get_username_provider(), + ] + + self.client_ctx.auth_baton = core.svn_auth_open(providers) + self.repos_url = "file://" + pathname2url(REPOS_PATH) + + def info_receiver(self, path, info, pool): + """Squirrel away the output from 'svn info' so that the unit tests + can get at them.""" + self.path = path + self.info = info + + def test_checkout(self): + """Test svn_client_checkout2.""" + + rev = core.svn_opt_revision_t() + rev.kind = core.svn_opt_revision_head + + path = os.path.join(tempfile.gettempdir(), 'checkout') + + self.assertRaises(ValueError, client.checkout2, + self.repos_url, path, None, None, True, True, + self.client_ctx) + + client.checkout2(self.repos_url, path, rev, rev, True, True, + self.client_ctx) + + def test_info(self): + """Test scope of get_logs callbacks""" + + # Run info + revt = core.svn_opt_revision_t() + revt.kind = core.svn_opt_revision_head + repos_url = "file://" + pathname2url(REPOS_PATH) + client.info(repos_url, revt, revt, self.info_receiver, + False, self.client_ctx) + + # Check output from running info. This also serves to verify that + # the internal 'info' object is still valid + self.assertEqual(self.path, os.path.basename(REPOS_PATH)) + self.info.assert_valid() + self.assertEqual(self.info.URL, repos_url) + self.assertEqual(self.info.repos_root_URL, repos_url) + + + def test_uuid_from_url(self): + """Test svn_client_uuid_from_url on a file:// URL""" + self.assert_(isinstance( + client.uuid_from_url(self.repos_url, self.client_ctx), + types.StringTypes)) + + def test_url_from_path(self): + """Test svn_client_url_from_path for a file:// URL""" + self.assertEquals(client.url_from_path(self.repos_url), self.repos_url) + + rev = core.svn_opt_revision_t() + rev.kind = core.svn_opt_revision_head + + path = os.path.join(tempfile.gettempdir(), 'url_from_path') + + client.checkout2(self.repos_url, path, rev, rev, True, True, + self.client_ctx) + + self.assertEquals(client.url_from_path(path), self.repos_url) + + def test_uuid_from_path(self): + """Test svn_client_uuid_from_path.""" + rev = core.svn_opt_revision_t() + rev.kind = core.svn_opt_revision_head + + path = os.path.join(tempfile.gettempdir(), 'uuid_from_path') + + client.checkout2(self.repos_url, path, rev, rev, True, True, + self.client_ctx) + + wc_adm = wc.adm_open3(None, path, False, 0, None) + + self.assertEquals(client.uuid_from_path(path, wc_adm, self.client_ctx), + client.uuid_from_url(self.repos_url, self.client_ctx)) + + self.assert_(isinstance(client.uuid_from_path(path, wc_adm, + self.client_ctx), types.StringTypes)) + + def test_open_ra_session(self): + """Test svn_client_open_ra_session().""" + client.open_ra_session(self.repos_url, self.client_ctx) + +def suite(): + return unittest.makeSuite(SubversionRepositoryTestCase, 'test', + suiteClass=SubversionRepositoryTestSetup) + +if __name__ == '__main__': + runner = unittest.TextTestRunner() + runner.run(suite()) diff -Nur subversion-1.3.1/subversion/bindings/swig/python/tests/client.py.orig subversion-1.3.1.new/subversion/bindings/swig/python/tests/client.py.orig --- subversion-1.3.1/subversion/bindings/swig/python/tests/client.py.orig 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/python/tests/client.py.orig 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,111 @@ +import unittest, os, tempfile, types + +from svn import core, repos, fs, delta, client, wc + +from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \ + REPOS_PATH +from urllib import pathname2url + +class SubversionRepositoryTestCase(unittest.TestCase): + """Test cases for the Subversion repository layer""" + + def setUp(self): + """Load a Subversion repository""" + self.client_ctx = client.svn_client_create_context() + + providers = [ + client.svn_client_get_simple_provider(), + client.svn_client_get_username_provider(), + ] + + self.client_ctx.auth_baton = core.svn_auth_open(providers) + self.repos_url = "file://" + pathname2url(REPOS_PATH) + + def info_receiver(self, path, info, pool): + """Squirrel away the output from 'svn info' so that the unit tests + can get at them.""" + self.path = path + self.info = info + + def test_checkout(self): + """Test svn_client_checkout2.""" + + rev = core.svn_opt_revision_t() + rev.kind = core.svn_opt_revision_head + + path = os.path.join(tempfile.gettempdir(), 'checkout') + + self.assertRaises(ValueError, client.checkout2, + self.repos_url, path, None, None, True, True, + self.client_ctx) + + client.checkout2(self.repos_url, path, rev, rev, True, True, + self.client_ctx) + + def test_info(self): + """Test scope of get_logs callbacks""" + + # Run info + revt = core.svn_opt_revision_t() + revt.kind = core.svn_opt_revision_head + repos_url = "file://" + pathname2url(REPOS_PATH) + client.info(repos_url, revt, revt, self.info_receiver, + False, self.client_ctx) + + # Check output from running info. This also serves to verify that + # the internal 'info' object is still valid + self.assertEqual(self.path, os.path.basename(REPOS_PATH)) + self.info.assert_valid() + self.assertEqual(self.info.URL, repos_url) + self.assertEqual(self.info.repos_root_URL, repos_url) + + + def test_uuid_from_url(self): + """Test svn_client_uuid_from_url on a file:// URL""" + self.assert_(isinstance( + client.uuid_from_url(self.repos_url, self.client_ctx), + types.StringTypes)) + + def test_url_from_path(self): + """Test svn_client_url_from_path for a file:// URL""" + self.assertEquals(client.url_from_path(self.repos_url), self.repos_url) + + rev = core.svn_opt_revision_t() + rev.kind = core.svn_opt_revision_head + + path = os.path.join(tempfile.gettempdir(), 'url_from_path') + + client.checkout2(self.repos_url, path, rev, rev, True, True, + self.client_ctx) + + self.assertEquals(client.url_from_path(path), self.repos_url) + + def test_uuid_from_path(self): + """Test svn_client_uuid_from_path.""" + rev = core.svn_opt_revision_t() + rev.kind = core.svn_opt_revision_head + + path = os.path.join(tempfile.gettempdir(), 'uuid_from_path') + + client.checkout2(self.repos_url, path, rev, rev, True, True, + self.client_ctx) + + wc_adm = wc.adm_open3(None, path, False, 0, None) + + self.assertEquals(client.uuid_from_path(path, wc_adm, self.client_ctx), + client.uuid_from_url(self.repos_url, self.client_ctx)) + + self.assert_(isinstance(client.uuid_from_path(path, wc_adm, + self.client_ctx), types.StringTypes)) + + def test_open_ra_session(self): + """Test svn_client_open_ra_session().""" + client.open_ra_session(self.repos_url, self.client_ctx) + +def suite(): + return unittest.makeSuite(SubversionRepositoryTestCase, 'test', + suiteClass=SubversionRepositoryTestSetup) + +if __name__ == '__main__': + runner = unittest.TextTestRunner() + runner.run(suite()) diff -Nur subversion-1.3.1/subversion/bindings/swig/python/tests/ra.py subversion-1.3.1.new/subversion/bindings/swig/python/tests/ra.py --- subversion-1.3.1/subversion/bindings/swig/python/tests/ra.py 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/python/tests/ra.py 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,136 @@ +import unittest, os + +from svn import core, repos, fs, delta, client, ra + +from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \ + REPOS_PATH +from urllib import pathname2url + +class SubversionRepositoryTestCase(unittest.TestCase): + """Test cases for the Subversion repository layer""" + + def setUp(self): + """Load a Subversion repository""" + + ra.initialize() + + self.repos_url = "file://" + pathname2url(REPOS_PATH) + + # Open repository directly for cross-checking + self.repos = repos.open(REPOS_PATH) + self.fs = repos.fs(self.repos) + + callbacks = ra.callbacks2_t() + + self.ra_ctx = ra.open2(self.repos_url, callbacks, None, None) + + def test_get_repos_root(self): + root = ra.get_repos_root(self.ra_ctx) + self.assertEqual(root,self.repos_url) + + def test_get_uuid(self): + ra_uuid = ra.get_uuid(self.ra_ctx) + fs_uuid = fs.get_uuid(self.fs) + self.assertEqual(ra_uuid,fs_uuid) + + def test_get_lastest_revnum(self): + ra_revnum = ra.get_latest_revnum(self.ra_ctx) + fs_revnum = fs.youngest_rev(self.fs) + self.assertEqual(ra_revnum,fs_revnum) + + def test_get_dir(self): + (dirents,_,props) = ra.get_dir(self.ra_ctx, '', 1) + self.assertTrue(dirents.has_key('trunk')) + self.assertTrue(dirents.has_key('branches')) + self.assertTrue(dirents.has_key('tags')) + self.assertEqual(dirents['trunk'].kind, core.svn_node_dir) + self.assertEqual(dirents['branches'].kind, core.svn_node_dir) + self.assertEqual(dirents['tags'].kind, core.svn_node_dir) + self.assertTrue(props.has_key(core.SVN_PROP_ENTRY_UUID)) + self.assertTrue(props.has_key(core.SVN_PROP_ENTRY_LAST_AUTHOR)) + + (dirents,_,_) = ra.get_dir(self.ra_ctx, 'trunk', 1) + + self.assertEqual(dirents, {}) + + (dirents,_,_) = ra.get_dir(self.ra_ctx, 'trunk', 10) + + self.assertTrue(dirents.has_key('README2.txt')) + self.assertEqual(dirents['README2.txt'].kind,core.svn_node_file) + + def test_commit(self): + def my_callback(revision, date, author, baton): + self.assertEqual(info.revision, fs.youngest_rev(self.fs)) + + editor, edit_baton = ra.get_commit_editor(self.ra_ctx, "foobar", my_callback, None, False) + root = delta.editor_invoke_open_root(editor, edit_baton, 4) + child = delta.editor_invoke_add_directory(editor, "bla", root, None, 0) + delta.editor_invoke_close_edit(editor, edit_baton) + + def test_commit(self): + def my_callback(revision, date, author): + self.assertEqual(revision, fs.youngest_rev(self.fs)) + + editor, edit_baton = ra.get_commit_editor(self.ra_ctx, "foobar", my_callback, None, False) + root = delta.editor_invoke_open_root(editor, edit_baton, 4) + child = delta.editor_invoke_add_directory(editor, "blah", root, None, 0) + delta.editor_invoke_close_edit(editor, edit_baton) + + def test_commit(self): + def my_callback(revision, date, author): + self.assertEqual(revision, fs.youngest_rev(self.fs)) + + editor, edit_baton = ra.get_commit_editor(self.ra_ctx, "foobar", my_callback, None, False) + root = delta.editor_invoke_open_root(editor, edit_baton, 4) + child = delta.editor_invoke_add_directory(editor, "blah", root, None, 0) + delta.editor_invoke_close_edit(editor, edit_baton) + + def test_get_locations(self): + locations = ra.get_locations(self.ra_ctx, "/trunk/README.txt", 2, range(1,5)) + self.assertEqual(locations, { + 2: '/trunk/README.txt', + 3: '/trunk/README.txt', + 4: '/trunk/README.txt'}) + + def test_get_file_revs(self): + def rev_handler(path, rev, rev_props, prop_diffs, pool): + self.assert_(rev == 2 or rev == 3) + self.assertEqual(path, "/trunk/README.txt") + if rev == 2: + self.assertEqual(rev_props, { + 'svn:log': 'Added README.', + 'svn:author': 'john', + 'svn:date': '2005-04-01T13:12:18.216267Z' + }) + self.assertEqual(prop_diffs, {}) + elif rev == 3: + self.assertEqual(rev_props, { + 'svn:log': 'Fixed README.\n', + 'svn:author': 'kate', + 'svn:date': '2005-04-01T13:24:58.234643Z' + }) + self.assertEqual(prop_diffs, {'svn:mime-type': 'text/plain', 'svn:eol-style': 'native'}) + + ra.get_file_revs(self.ra_ctx, "trunk/README.txt", 0, 10, rev_handler) + + def test_update(self): + class TestEditor(delta.Editor): + pass + + editor = TestEditor() + + e_ptr, e_baton = delta.make_editor(editor) + + reporter, reporter_baton = ra.do_update(self.ra_ctx, 10, "", True, e_ptr, e_baton) + + ra.reporter2_invoke_set_path(reporter, reporter_baton, "", 0, True, None) + + ra.reporter2_invoke_finish_report(reporter, reporter_baton) + +def suite(): + return unittest.makeSuite(SubversionRepositoryTestCase, 'test', + suiteClass=SubversionRepositoryTestSetup) + +if __name__ == '__main__': + runner = unittest.TextTestRunner() + runner.run(suite()) diff -Nur subversion-1.3.1/subversion/bindings/swig/python/tests/ra.py.orig subversion-1.3.1.new/subversion/bindings/swig/python/tests/ra.py.orig --- subversion-1.3.1/subversion/bindings/swig/python/tests/ra.py.orig 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/python/tests/ra.py.orig 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,136 @@ +import unittest, os + +from svn import core, repos, fs, delta, client, ra + +from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \ + REPOS_PATH +from urllib import pathname2url + +class SubversionRepositoryTestCase(unittest.TestCase): + """Test cases for the Subversion repository layer""" + + def setUp(self): + """Load a Subversion repository""" + + ra.initialize() + + self.repos_url = "file://" + pathname2url(REPOS_PATH) + + # Open repository directly for cross-checking + self.repos = repos.open(REPOS_PATH) + self.fs = repos.fs(self.repos) + + callbacks = ra.callbacks2_t() + + self.ra_ctx = ra.open2(self.repos_url, callbacks, None, None) + + def test_get_repos_root(self): + root = ra.get_repos_root(self.ra_ctx) + self.assertEqual(root,self.repos_url) + + def test_get_uuid(self): + ra_uuid = ra.get_uuid(self.ra_ctx) + fs_uuid = fs.get_uuid(self.fs) + self.assertEqual(ra_uuid,fs_uuid) + + def test_get_lastest_revnum(self): + ra_revnum = ra.get_latest_revnum(self.ra_ctx) + fs_revnum = fs.youngest_rev(self.fs) + self.assertEqual(ra_revnum,fs_revnum) + + def test_get_dir(self): + (dirents,_,props) = ra.get_dir(self.ra_ctx, '', 1) + self.assertTrue(dirents.has_key('trunk')) + self.assertTrue(dirents.has_key('branches')) + self.assertTrue(dirents.has_key('tags')) + self.assertEqual(dirents['trunk'].kind, core.svn_node_dir) + self.assertEqual(dirents['branches'].kind, core.svn_node_dir) + self.assertEqual(dirents['tags'].kind, core.svn_node_dir) + self.assertTrue(props.has_key(core.SVN_PROP_ENTRY_UUID)) + self.assertTrue(props.has_key(core.SVN_PROP_ENTRY_LAST_AUTHOR)) + + (dirents,_,_) = ra.get_dir(self.ra_ctx, 'trunk', 1) + + self.assertEqual(dirents, {}) + + (dirents,_,_) = ra.get_dir(self.ra_ctx, 'trunk', 10) + + self.assertTrue(dirents.has_key('README2.txt')) + self.assertEqual(dirents['README2.txt'].kind,core.svn_node_file) + + def test_commit(self): + def my_callback(revision, date, author, baton): + self.assertEqual(info.revision, fs.youngest_rev(self.fs)) + + editor, edit_baton = ra.get_commit_editor(self.ra_ctx, "foobar", my_callback, None, False) + root = delta.editor_invoke_open_root(editor, edit_baton, 4) + child = delta.editor_invoke_add_directory(editor, "bla", root, None, 0) + delta.editor_invoke_close_edit(editor, edit_baton) + + def test_commit(self): + def my_callback(revision, date, author): + self.assertEqual(revision, fs.youngest_rev(self.fs)) + + editor, edit_baton = ra.get_commit_editor(self.ra_ctx, "foobar", my_callback, None, False) + root = delta.editor_invoke_open_root(editor, edit_baton, 4) + child = delta.editor_invoke_add_directory(editor, "blah", root, None, 0) + delta.editor_invoke_close_edit(editor, edit_baton) + + def test_commit(self): + def my_callback(revision, date, author): + self.assertEqual(revision, fs.youngest_rev(self.fs)) + + editor, edit_baton = ra.get_commit_editor(self.ra_ctx, "foobar", my_callback, None, False) + root = delta.editor_invoke_open_root(editor, edit_baton, 4) + child = delta.editor_invoke_add_directory(editor, "blah", root, None, 0) + delta.editor_invoke_close_edit(editor, edit_baton) + + def test_get_locations(self): + locations = ra.get_locations(self.ra_ctx, "/trunk/README.txt", 2, range(1,5)) + self.assertEqual(locations, { + 2: '/trunk/README.txt', + 3: '/trunk/README.txt', + 4: '/trunk/README.txt'}) + + def test_get_file_revs(self): + def rev_handler(path, rev, rev_props, prop_diffs, pool): + self.assert_(rev == 2 or rev == 3) + self.assertEqual(path, "/trunk/README.txt") + if rev == 2: + self.assertEqual(rev_props, { + 'svn:log': 'Added README.', + 'svn:author': 'john', + 'svn:date': '2005-04-01T13:12:18.216267Z' + }) + self.assertEqual(prop_diffs, {}) + elif rev == 3: + self.assertEqual(rev_props, { + 'svn:log': 'Fixed README.\n', + 'svn:author': 'kate', + 'svn:date': '2005-04-01T13:24:58.234643Z' + }) + self.assertEqual(prop_diffs, {'svn:mime-type': 'text/plain', 'svn:eol-style': 'native'}) + + ra.get_file_revs(self.ra_ctx, "trunk/README.txt", 0, 10, rev_handler) + + def test_update(self): + class TestEditor(delta.Editor): + pass + + editor = TestEditor() + + e_ptr, e_baton = delta.make_editor(editor) + + reporter, reporter_baton = ra.do_update(self.ra_ctx, 10, "", True, e_ptr, e_baton) + + ra.reporter2_invoke_set_path(reporter, reporter_baton, "", 0, True, None) + + ra.reporter2_invoke_finish_report(reporter, reporter_baton) + +def suite(): + return unittest.makeSuite(SubversionRepositoryTestCase, 'test', + suiteClass=SubversionRepositoryTestSetup) + +if __name__ == '__main__': + runner = unittest.TextTestRunner() + runner.run(suite()) diff -Nur subversion-1.3.1/subversion/bindings/swig/python/tests/run_all.py subversion-1.3.1.new/subversion/bindings/swig/python/tests/run_all.py --- subversion-1.3.1/subversion/bindings/swig/python/tests/run_all.py 2005-10-02 05:18:25.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/python/tests/run_all.py 2006-07-05 01:04:06.000000000 +0100 @@ -1,6 +1,6 @@ import sys, os bindir = os.path.dirname(sys.argv[0]) -sys.path[0:0] = [ os.getcwd(), "%s/.libs" % os.getcwd(), \ +sys.path[0:0] = [ bindir, os.getcwd(), "%s/.libs" % os.getcwd(), \ "%s/.." % bindir, "%s/../.libs" % bindir ] # OSes without RPATH support are going to have to do things here to make @@ -17,6 +17,9 @@ import unittest import pool import repository +import client +import ra +import wc import trac.versioncontrol.tests # Run all tests @@ -24,7 +27,10 @@ def suite(): """Run all tests""" suite = unittest.TestSuite() + suite.addTest(client.suite()) suite.addTest(pool.suite()) + suite.addTest(ra.suite()) + suite.addTest(wc.suite()) suite.addTest(repository.suite()) suite.addTest(trac.versioncontrol.tests.suite()); return suite diff -Nur subversion-1.3.1/subversion/bindings/swig/python/tests/wc.py subversion-1.3.1.new/subversion/bindings/swig/python/tests/wc.py --- subversion-1.3.1/subversion/bindings/swig/python/tests/wc.py 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/python/tests/wc.py 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,175 @@ +import unittest, os, tempfile +import shutil + +from svn import core, repos, wc, client +from libsvn.core import SubversionException + +from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \ + REPOS_PATH +from urllib import pathname2url + +class SubversionRepositoryTestCase(unittest.TestCase): + """Test cases for the Subversion working copy layer""" + + def setUp(self): + """Load a Subversion repository""" + + self.repos_url = "file://" + pathname2url(REPOS_PATH) + + # Open repository directly for cross-checking + self.repos = repos.open(REPOS_PATH) + self.fs = repos.fs(self.repos) + + self.path = tempfile.mktemp() + + client_ctx = client.create_context() + + rev = core.svn_opt_revision_t() + rev.kind = core.svn_opt_revision_head + + client.checkout2(self.repos_url, self.path, rev, rev, True, True, + client_ctx) + + self.wc = wc.adm_open3(None, self.path, True, -1, None) + + def test_entry(self): + wc_entry = wc.entry(self.path, self.wc, True) + + def test_lock(self): + lock = wc.add_lock(self.path, core.svn_lock_create(core.Pool()), self.wc) + self.assertEqual(True, wc.adm_locked(self.wc)) + self.assertEqual(True, wc.locked(self.path)) + wc.remove_lock(self.path, self.wc) + + def test_version(self): + wc.version() + + def test_access_path(self): + self.assertEqual(self.path, wc.adm_access_path(self.wc)) + + def test_is_adm_dir(self): + self.assertTrue(wc.is_adm_dir(".svn")) + self.assertFalse(wc.is_adm_dir(".foosvn")) + + def test_get_adm_dir(self): + self.assertTrue(isinstance(wc.get_adm_dir(), basestring)) + + def test_set_adm_dir(self): + self.assertRaises(SubversionException, wc.set_adm_dir, ".foobar") + self.assertTrue(wc.is_adm_dir(".svn")) + self.assertFalse(wc.is_adm_dir("_svn")) + self.assertFalse(wc.is_adm_dir(".foobar")) + wc.set_adm_dir("_svn") + self.assertTrue(wc.is_adm_dir("_svn")) + self.assertEqual("_svn", wc.get_adm_dir()) + wc.set_adm_dir(".svn") + self.assertFalse(wc.is_adm_dir("_svn")) + self.assertEqual(".svn", wc.get_adm_dir()) + + def test_init_traversal_info(self): + wc.init_traversal_info() + + def test_crawl_revisions2(self): + infos = [] + set_paths = [] + + def notify(info, pool): + infos.append(info) + + class MyReporter: + def __init__(self): + 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): + set_paths.append(path) + + def link_path(self, path, url, revision, start_empty, lock_token, + pool): + pass + + def delete_path(self, path, pool): + pass + + # Remove trunk/README.txt + readme_path = os.path.join(self.path, "trunk", "README.txt") + self.assert_(os.path.exists(readme_path)) + os.remove(readme_path) + + # Restore trunk/README.txt using crawl_revision2 + info = wc.init_traversal_info() + reporter = MyReporter() + wc.crawl_revisions2(self.path, self.wc, reporter, + True, True, False, notify, info) + + # Check that the report finished + self.assert_(reporter._finished_report) + self.assertEqual([''], set_paths) + self.assertEqual(1, len(infos)) + + # Check content of infos object + [info] = infos + self.assertEqual(readme_path, info.path) + self.assertEqual(core.svn_node_file, info.kind) + self.assertEqual(-1, info.revision) + + def test_create_notify(self): + wc.create_notify(self.path, wc.notify_add) + + def test_check_wc(self): + self.assertTrue(wc.check_wc(self.path) > 0) + + def test_get_ancestry(self): + self.assertEqual([self.repos_url, 12], + wc.get_ancestry(self.path, self.wc)) + + def test_status(self): + wc.status2(self.path, self.wc) + + def test_is_normal_prop(self): + self.failIf(wc.is_normal_prop('svn:wc:foo:bar')) + self.failIf(wc.is_normal_prop('svn:entry:foo:bar')) + self.assert_(wc.is_normal_prop('svn:foo:bar')) + self.assert_(wc.is_normal_prop('foreign:foo:bar')) + + def test_is_wc_prop(self): + self.assert_(wc.is_wc_prop('svn:wc:foo:bar')) + self.failIf(wc.is_wc_prop('svn:entry:foo:bar')) + self.failIf(wc.is_wc_prop('svn:foo:bar')) + self.failIf(wc.is_wc_prop('foreign:foo:bar')) + + def test_is_entry_prop(self): + self.assert_(wc.is_entry_prop('svn:entry:foo:bar')) + self.failIf(wc.is_entry_prop('svn:wc:foo:bar')) + self.failIf(wc.is_entry_prop('svn:foo:bar')) + self.failIf(wc.is_entry_prop('foreign:foo:bar')) + + def test_get_pristine_copy_path(self): + self.assertEqual( + wc.get_pristine_copy_path(os.path.join(self.path, 'foo')), + os.path.join(self.path, wc.get_adm_dir(), 'text-base', 'foo.svn-base')) + + def test_get_ignores(self): + self.assert_(isinstance(wc.get_ignores(None, self.wc), list)) + + def test_entries_read(self): + entries = wc.entries_read(self.wc, True) + + self.assertEqual(['', 'tags', 'branches', 'trunk'], entries.keys()) + + def tearDown(self): + wc.adm_close(self.wc) + shutil.rmtree(self.path) + +def suite(): + return unittest.makeSuite(SubversionRepositoryTestCase, 'test', + suiteClass=SubversionRepositoryTestSetup) + +if __name__ == '__main__': + runner = unittest.TextTestRunner() + runner.run(suite()) diff -Nur subversion-1.3.1/subversion/bindings/swig/svn_client.i subversion-1.3.1.new/subversion/bindings/swig/svn_client.i --- subversion-1.3.1/subversion/bindings/swig/svn_client.i 2006-01-04 17:20:08.000000000 +0000 +++ subversion-1.3.1.new/subversion/bindings/swig/svn_client.i 2006-07-05 01:04:06.000000000 +0100 @@ -25,6 +25,7 @@ #endif %include typemaps.i +%include constraints.i %include svn_global.swg %import core.i @@ -44,6 +45,11 @@ svn_client_ctx_t ** }; +%apply Pointer NONNULL { + const svn_opt_revision_t *revision, + const svn_opt_revision_t *peg_revision +}; + %apply const apr_array_header_t *STRINGLIST { const apr_array_header_t *targets, const apr_array_header_t *diff_options @@ -66,6 +72,16 @@ #ifdef SWIGPYTHON %apply svn_stream_t *WRAPPED_STREAM { svn_stream_t * }; + +/* members of svn_client_ctx_t */ +%apply void *PY_AS_VOID { + void *notify_baton, + void *log_msg_baton, + void *cancel_baton, + void *notify_baton2, + void *log_msg_baton2, + void *progress_baton +}; #endif /* ----------------------------------------------------------------------- @@ -200,6 +216,18 @@ } /* ----------------------------------------------------------------------- + Callback: svn_info_receiver_t + svn_client_info() +*/ + +%typemap(python, in) (svn_info_receiver_t receiver, + void *receiver_baton) { + $1 = svn_swig_py_info_receiver_func; + $2 = (void *)$input; +} + + +/* ----------------------------------------------------------------------- We use 'svn_wc_status_t *' in some custom code, but it isn't in the API anywhere. Thus, SWIG doesn't generate a typemap entry for it. by adding a simple declaration here, SWIG will insert a name for it. @@ -483,6 +511,24 @@ %include svn_time_h.swg %include svn_client_h.swg +#ifdef SWIGPYTHON + +/* provide Python with access to some thunks. */ +%constant svn_cancel_func_t svn_swig_py_cancel_func; +%constant svn_client_get_commit_log2_t svn_swig_py_get_commit_log_func; +%constant svn_wc_notify_func2_t svn_swig_py_notify_func; + +#endif + +#ifdef SWIGPYTHON + +/* provide Python with access to some thunks. */ +%constant svn_cancel_func_t svn_swig_py_cancel_func; +%constant svn_client_get_commit_log2_t svn_swig_py_get_commit_log_func; +%constant svn_wc_notify_func2_t svn_swig_py_notify_func; + +#endif + #ifdef SWIGRUBY %inline %{ static VALUE diff -Nur subversion-1.3.1/subversion/bindings/swig/svn_client.i.orig subversion-1.3.1.new/subversion/bindings/swig/svn_client.i.orig --- subversion-1.3.1/subversion/bindings/swig/svn_client.i.orig 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/svn_client.i.orig 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,558 @@ +/* + * svn_client.i : SWIG interface file for svn_client.h + * + * ==================================================================== + * Copyright (c) 2000-2003 CollabNet. All rights reserved. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://subversion.tigris.org/license-1.html. + * If newer versions of this license are posted there, you may use a + * newer version instead, at your option. + * + * This software consists of voluntary contributions made by many + * individuals. For exact contribution history, see the revision + * history and logs, available at http://subversion.tigris.org/. + * ==================================================================== + */ + +#if defined(SWIGPERL) +%module "SVN::_Client" +#elif defined(SWIGRUBY) +%module "svn::ext::client" +#else +%module client +#endif + +%include typemaps.i +%include constraints.i + +%include svn_global.swg +%import core.i +%import apr.swg +%import svn_types.swg +%import svn_string.swg +%import svn_delta.i +%import svn_wc.i + +/* ----------------------------------------------------------------------- + %apply-ing of typemaps defined elsewhere +*/ + +%apply SWIGTYPE **OUTPARAM { + svn_client_commit_info_t **, + svn_auth_provider_object_t **, + svn_client_ctx_t ** +}; + +%apply Pointer NONNULL { + const svn_opt_revision_t *revision, + const svn_opt_revision_t *peg_revision +}; + +%apply const apr_array_header_t *STRINGLIST { + const apr_array_header_t *targets, + const apr_array_header_t *diff_options +}; + +%apply const char *MAY_BE_NULL { + const char *native_eol, + const char *comment +}; + +/* svn_client_propget(), svn_client_proplist(), svn_client_revprop_list() */ +%apply apr_hash_t **PROPHASH { apr_hash_t **props }; + +/* svn_client_url_from_path(), svn_client_uuid_from_url() + * svn_client_uuid_from_path */ +%apply const char **OUTPUT { + const char **url, + const char **uuid +}; + +#ifdef SWIGPYTHON +%apply svn_stream_t *WRAPPED_STREAM { svn_stream_t * }; + +/* members of svn_client_ctx_t */ +%apply void *PY_AS_VOID { + void *notify_baton, + void *log_msg_baton, + void *cancel_baton, + void *notify_baton2, + void *log_msg_baton2, + void *progress_baton +}; +#endif + +/* ----------------------------------------------------------------------- + svn_client_proplist() + returns apr_array_header_t * +*/ + +%typemap(in, numinputs=0) apr_array_header_t **props (apr_array_header_t *temp) { + $1 = &temp; +} + +/* svn_client_proplist_item_t is used exclusively for svn_client_proplist(). + The python bindings convert it to a native python tuple. */ +#ifdef SWIGPYTHON + %ignore svn_client_proplist_item_t; +#endif +%typemap(python, argout, fragment="t_output_helper") apr_array_header_t **props +{ + svn_client_proplist_item_t **ppitem; + int i; + int nelts = (*$1)->nelts; + PyObject *list = PyList_New(nelts); + if (list == NULL) + SWIG_fail; + ppitem = (svn_client_proplist_item_t **)(*$1)->elts; + for (i = 0; i < nelts; ++i, ++ppitem) { + PyObject *item = PyTuple_New(2); + PyObject *name = PyString_FromStringAndSize((*ppitem)->node_name->data, + (*ppitem)->node_name->len); + PyObject *hash = svn_swig_py_prophash_to_dict((*ppitem)->prop_hash); + + if (item == NULL || name == NULL || hash == NULL) { + Py_XDECREF(item); + Py_XDECREF(name); + Py_XDECREF(hash); + Py_DECREF(list); + SWIG_fail; + } + PyTuple_SET_ITEM(item, 0, name); + PyTuple_SET_ITEM(item, 1, hash); + + PyList_SET_ITEM(list, i, item); + } + $result = t_output_helper($result, list); +} + +%typemap(ruby, argout) apr_array_header_t **props +{ + $result = svn_swig_rb_apr_array_to_array_proplist_item(*$1); +} + +%typemap(ruby, out) apr_hash_t *prop_hash +{ + $result = svn_swig_rb_prop_hash_to_hash($1); +} + +%typemap(perl5,argout) apr_array_header_t **props { + $result = svn_swig_pl_convert_array(*$1, + $descriptor(svn_client_proplist_item_t *)); + argvi++; +} + +%typemap(perl5,out) apr_hash_t *prop_hash { + $result = svn_swig_pl_prophash_to_hash($1); + argvi++; +} + +/* ----------------------------------------------------------------------- + Callback: svn_client_get_commit_log_t + svn_client_ctx_t +*/ + +%typemap(python,in) (svn_client_get_commit_log_t log_msg_func, + void *log_msg_baton) { + + $1 = svn_swig_py_get_commit_log_func; + $2 = $input; /* our function is the baton. */ +} + +%typemap(ruby, in) (svn_client_get_commit_log2_t log_msg_func2, + void *log_msg_baton2) +{ + $1 = svn_swig_rb_get_commit_log_func2; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +/* ----------------------------------------------------------------------- + Callback: svn_cancel_func_t + svn_client_ctx_t +*/ + +%typemap(ruby, in) (svn_cancel_func_t cancel_func, void *cancel_baton) +{ + $1 = svn_swig_rb_cancel_func; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +/* ----------------------------------------------------------------------- + Callback: svn_wc_notify_func2_t + svn_client_ctx_t +*/ + +%typemap(ruby, in) (svn_wc_notify_func2_t notify_func2, void *notify_baton2) +{ + $1 = svn_swig_rb_notify_func2; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + + +/* ----------------------------------------------------------------------- + Callback: svn_client_blame_receiver_t + svn_client_blame() +*/ + +%typemap(python, in) (svn_client_blame_receiver_t receiver, + void *receiver_baton) { + $1 = svn_swig_py_client_blame_receiver_func; + $2 = (void *)$input; +} + +%typemap(perl5, in) (svn_client_blame_receiver_t receiver, + void *receiver_baton) { + $1 = svn_swig_pl_blame_func; + $2 = $input; /* our function is the baton. */ +} + +%typemap(ruby, in) (svn_client_blame_receiver_t receiver, + void *receiver_baton) +{ + $1 = svn_swig_rb_client_blame_receiver_func; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +/* ----------------------------------------------------------------------- + Callback: svn_info_receiver_t + svn_client_info() +*/ + +%typemap(python, in) (svn_info_receiver_t receiver, + void *receiver_baton) { + $1 = svn_swig_py_info_receiver_func; + $2 = (void *)$input; +} + + +/* ----------------------------------------------------------------------- + We use 'svn_wc_status_t *' in some custom code, but it isn't in the + API anywhere. Thus, SWIG doesn't generate a typemap entry for it. by + adding a simple declaration here, SWIG will insert a name for it. + FIXME: This may be untrue. See svn_wc_status, etc. +*/ +%types(svn_wc_status_t *); + +/* We also need SWIG to wrap svn_dirent_t and svn_lock_t for us. They + don't appear in any API, but svn_client_ls returns a hash of pointers + to dirents and locks. */ +%types(svn_dirent_t *); +%types(svn_lock_t *); + +/* ----------------------------------------------------------------------- + thunk the various authentication prompt functions. + PERL NOTE: store the inputed SV in _global_callback for use in the + later argout typemap +*/ +%typemap(perl5, in) (svn_auth_simple_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_pl_thunk_simple_prompt; + _global_callback = $input; + $2 = (void *) _global_callback; +} +%typemap(python, in) (svn_auth_simple_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_py_auth_simple_prompt_func; + $2 = $input; +} +%typemap(ruby, in) (svn_auth_simple_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_rb_auth_simple_prompt_func; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +%typemap(perl5, in) (svn_auth_username_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_pl_thunk_username_prompt; + _global_callback = $input; + $2 = (void *) _global_callback; +} +%typemap(python, in) (svn_auth_username_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_py_auth_username_prompt_func; + $2 = $input; +} +%typemap(ruby, in) (svn_auth_username_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_rb_auth_username_prompt_func; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +%typemap(perl5, in) (svn_auth_ssl_server_trust_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_pl_thunk_ssl_server_trust_prompt; + _global_callback = $input; + $2 = (void *) _global_callback; +} +%typemap(python, in) (svn_auth_ssl_server_trust_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_py_auth_ssl_server_trust_prompt_func; + $2 = $input; +} +%typemap(ruby, in) (svn_auth_ssl_server_trust_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_rb_auth_ssl_server_trust_prompt_func; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +%typemap(perl5, in) (svn_auth_ssl_client_cert_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_pl_thunk_ssl_client_cert_prompt; + _global_callback = $input; + $2 = (void *) _global_callback; +} +%typemap(python, in) (svn_auth_ssl_client_cert_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_py_auth_ssl_client_cert_prompt_func; + $2 = $input; +} +%typemap(ruby, in) (svn_auth_ssl_client_cert_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_rb_auth_ssl_client_cert_prompt_func; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +%typemap(perl5, in) (svn_auth_ssl_client_cert_pw_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_pl_thunk_ssl_client_cert_pw_prompt; + _global_callback = $input; + $2 = (void *) _global_callback; +} +%typemap(python, in) (svn_auth_ssl_client_cert_pw_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_py_auth_ssl_client_cert_pw_prompt_func; + $2 = $input; +} +%typemap(ruby, in) (svn_auth_ssl_client_cert_pw_prompt_func_t prompt_func, + void *prompt_baton) { + $1 = svn_swig_rb_auth_ssl_client_cert_pw_prompt_func; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +/* ----------------------------------------------------------------------- + * For all the various functions that set a callback baton create a reference + * for the baton (which in this case is an SV pointing to the callback) + * and make that a return from the function. The perl side should + * then store the return in the object the baton is attached to. + * If the function already returns a value then this value is follows that + * function. In the case of the prompt functions auth_open_helper in Core.pm + * is used to split up these values. +*/ +%typemap(perl5, argout) void *CALLBACK_BATON (SV * _global_callback) { + /* callback baton */ + $result = sv_2mortal (newRV_inc (_global_callback)); argvi++; } + +%typemap(perl5, in) void *CALLBACK_BATON (SV * _global_callback) { + _global_callback = $input; + $1 = (void *) _global_callback; +} + +#ifdef SWIGPERL +%apply void *CALLBACK_BATON { + void *prompt_baton, + void *notify_baton, + void *log_msg_baton, + void *cancel_baton +} +#endif + +#ifdef SWIGRUBY +%apply void *CALLBACK_BATON +{ + void *notify_baton2, + void *log_msg_baton2, + void *cancel_baton +} +#endif + +/* ----------------------------------------------------------------------- + * Convert perl hashes back into apr_hash_t * for setting the config + * member of the svn_client_ctx_t. This is an ugly hack, it will + * always allocate the new apr_hash_t out of the global current_pool + * It would be better to make apr_hash_t's into magic variables in + * perl that are tied to the apr_hash_t interface. This would + * remove the need to convert to and from perl hashs all the time. + */ +%typemap(perl5, in) apr_hash_t *config { + $1 = svn_swig_pl_objs_to_hash_by_name ($input, "svn_config_t *", + svn_swig_pl_make_pool ((SV *)NULL)); +} + +%typemap(perl5, out) apr_hash_t *config { + $result = svn_swig_pl_convert_hash($1, + $descriptor(svn_config_t *)); + argvi++; +} + +#ifdef SWIGRUBY +%runtime %{ + #include + #include + + static apr_pool_t * + _svn_client_pool(void) + { + static apr_pool_t *__svn_client_pool = NULL; + if (!__svn_client_pool) { + apr_pool_create(&__svn_client_pool, NULL); + } + return __svn_client_pool; + } + + static apr_pool_t * + _svn_client_config_pool(void) + { + static apr_pool_t *__svn_client_config_pool = NULL; + if (!__svn_client_config_pool) { + apr_pool_create(&__svn_client_config_pool, _svn_client_pool()); + } + return __svn_client_config_pool; + } +%} +#endif + +%typemap(ruby, argout) apr_hash_t *config { + if ($1) + apr_pool_clear(_svn_client_config_pool()); +} + +%typemap(ruby, in) apr_hash_t *config { + $1 = svn_swig_rb_hash_to_apr_hash_swig_type($input, "svn_config_t *", + _svn_client_config_pool()); +} + +%typemap(ruby, out) apr_hash_t *config { + $result = svn_swig_rb_apr_hash_to_hash_swig_type($1, "svn_config_t *"); +} + +/* ----------------------------------------------------------------------- + * override default typemap for svn_client_commit_info_t for perl. Some calls + * never allocate and fill the commit_info struct. This lets us return + * undef for them. Otherwise the object we pass back can cause crashes */ +%typemap(perl5, in, numinputs=0) svn_client_commit_info_t ** + ( svn_client_commit_info_t * temp ) { + temp = NULL; + $1 = &temp; +} + +%typemap(perl5, argout) svn_client_commit_info_t ** { + if ($1 == NULL) { + $result = &PL_sv_undef; + argvi++; + } else { + $result = sv_newmortal(); + SWIG_MakePtr($result, (void *)*$1, + $*1_descriptor, 0); + argvi++; + } +} + +/* ----------------------------------------------------------------------- + * wcprop_changes member of svn_client_commit_info needs to be + * converted back and forth from an array */ + +%typemap(perl5, out) apr_array_header_t *wcprop_changes { + $result = svn_swig_pl_convert_array($1, + $descriptor(svn_prop_t *)); + argvi++; +} + +/* ----------------------------------------------------------------------- + * wrap svn_client_create_context */ + +%typemap(perl5,in,numinputs=0) svn_client_ctx_t ** (svn_client_ctx_t *temp) { + $1 = &temp; +} + +%typemap(perl5,argout) svn_client_ctx_t ** { + (*$1)->notify_func = svn_swig_pl_notify_func; + (*$1)->notify_baton = (void *) &PL_sv_undef; + (*$1)->log_msg_func = svn_swig_pl_get_commit_log_func; + (*$1)->log_msg_baton = (void *) &PL_sv_undef; + (*$1)->cancel_func = svn_swig_pl_cancel_func; + (*$1)->cancel_baton = (void *) &PL_sv_undef; + $result = sv_newmortal(); + SWIG_MakePtr($result, (void *)*$1, + $*1_descriptor, 0); + argvi++; +} + +/* svn_client_update2 */ +%typemap(ruby, in, numinputs=0) apr_array_header_t **result_revs (apr_array_header_t *temp) +{ + $1 = &temp; +} + +%typemap(ruby, argout, fragment="output_helper") apr_array_header_t **result_revs +{ + $result = output_helper($result, svn_swig_rb_apr_array_to_array_svn_rev(*$1)); +} + +/* ----------------------------------------------------------------------- */ + +%{ +#ifdef SWIGPYTHON +#include "swigutil_py.h" +#endif + +#ifdef SWIGPERL +#include "swigutil_pl.h" +#endif + +#ifdef SWIGRUBY +#include +#include +#include "swigutil_rb.h" +#endif +%} + +%include svn_time_h.swg +%include svn_client_h.swg + +#ifdef SWIGPYTHON + +/* provide Python with access to some thunks. */ +%constant svn_cancel_func_t svn_swig_py_cancel_func; +%constant svn_client_get_commit_log2_t svn_swig_py_get_commit_log_func; +%constant svn_wc_notify_func2_t svn_swig_py_notify_func; + +#endif + +#ifdef SWIGRUBY +%inline %{ +static VALUE +svn_client_set_log_msg_func2(svn_client_ctx_t *ctx, + svn_client_get_commit_log2_t log_msg_func2, + void *log_msg_baton2, + apr_pool_t *pool) +{ + ctx->log_msg_func2 = log_msg_func2; + ctx->log_msg_baton2 = log_msg_baton2; + return (VALUE)log_msg_baton2; +} + +static VALUE +svn_client_set_notify_func2(svn_client_ctx_t *ctx, + svn_wc_notify_func2_t notify_func2, + void *notify_baton2, + apr_pool_t *pool) +{ + ctx->notify_func2 = notify_func2; + ctx->notify_baton2 = notify_baton2; + return (VALUE)notify_baton2; +} + +static VALUE +svn_client_set_cancel_func(svn_client_ctx_t *ctx, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *pool) +{ + ctx->cancel_func = cancel_func; + ctx->cancel_baton = cancel_baton; + return (VALUE)cancel_baton; +} +%} +#endif diff -Nur subversion-1.3.1/subversion/bindings/swig/svn_delta.i subversion-1.3.1.new/subversion/bindings/swig/svn_delta.i --- subversion-1.3.1/subversion/bindings/swig/svn_delta.i 2005-09-29 00:56:52.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/svn_delta.i 2006-07-05 01:04:06.000000000 +0100 @@ -47,7 +47,8 @@ const char *error_info, const char *copyfrom_path, const char *copy_path, - const char *base_checksum + const char *base_checksum, + const char *text_checksum }; #ifdef SWIGPYTHON @@ -145,6 +146,17 @@ %include svn_delta_h.swg +#ifdef SWIGPYTHON +%inline %{ +svn_error_t *svn_delta_invoke_txdelta_window_handler ( + svn_txdelta_window_handler_t handler, + svn_txdelta_window_t *window, void *baton) { + return handler(window, baton); +} +%} +#endif + + /* ----------------------------------------------------------------------- handle svn_txdelta_to_svndiff(). */ diff -Nur subversion-1.3.1/subversion/bindings/swig/svn_ra.i subversion-1.3.1.new/subversion/bindings/swig/svn_ra.i --- subversion-1.3.1/subversion/bindings/swig/svn_ra.i 2005-10-04 16:43:40.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/svn_ra.i 2006-07-05 01:06:13.000000000 +0100 @@ -25,6 +25,7 @@ #endif %include typemaps.i +%include constraints.i %include svn_global.swg %import apr.swg @@ -48,13 +49,16 @@ const svn_ra_reporter2_t **reporter, void **report_baton, svn_dirent_t **dirent, - svn_lock_t **lock + svn_lock_t **lock, + const svn_delta_editor_t ** }; %apply apr_hash_t **PROPHASH { apr_hash_t **props }; +%apply apr_hash_t **DIRENTHASH { apr_hash_t **dirents }; %apply const char *MAY_BE_NULL { - const char *comment + const char *comment, + const char *lock_token }; %apply apr_hash_t *STRING_TO_STRING { @@ -112,6 +116,11 @@ svn_swig_rb_setup_ra_callbacks(&$1, &$2, $input, _global_pool); } +%typemap(python, in) (const svn_ra_callbacks2_t *callbacks, + void *callback_baton) { + svn_swig_py_setup_ra_callbacks(&$1, &$2, $input, _global_pool); +} + %typemap(perl5, in) apr_hash_t *config { $1 = svn_swig_pl_objs_to_hash_by_name ($input, "svn_config_t *", _global_pool); @@ -134,6 +143,22 @@ $1 = svn_swig_rb_hash_to_apr_hash_revnum($input, _global_pool); } +#ifdef SWIGPYTHON +%typemap(in) (svn_ra_file_rev_handler_t handler, void *handler_baton) +{ + $1 = svn_swig_py_ra_file_rev_handler_func; + $2 = (void *)$input; +} +#endif + +#ifdef SWIGPYTHON +%typemap(in) (const svn_ra_reporter2_t *reporter, void *report_baton) +{ + $1 = (svn_ra_reporter2_t *)&swig_py_ra_reporter2; + $2 = (void *)$input; +} +#endif + /* ----------------------------------------------------------------------- */ %{ diff -Nur subversion-1.3.1/subversion/bindings/swig/svn_ra.i.orig subversion-1.3.1.new/subversion/bindings/swig/svn_ra.i.orig --- subversion-1.3.1/subversion/bindings/swig/svn_ra.i.orig 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/svn_ra.i.orig 2006-07-05 01:04:06.000000000 +0100 @@ -0,0 +1,184 @@ +/* + * svn_ra.i : SWIG interface file for svn_ra.h + * + * ==================================================================== + * Copyright (c) 2000-2003 CollabNet. All rights reserved. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://subversion.tigris.org/license-1.html. + * If newer versions of this license are posted there, you may use a + * newer version instead, at your option. + * + * This software consists of voluntary contributions made by many + * individuals. For exact contribution history, see the revision + * history and logs, available at http://subversion.tigris.org/. + * ==================================================================== + */ + +#if defined(SWIGPERL) +%module "SVN::_Ra" +#elif defined(SWIGRUBY) +%module "svn::ext::ra" +#else +%module ra +#endif + +%include typemaps.i +%include constraints.i + +%include svn_global.swg +%import apr.swg +%import core.i +%import svn_types.swg +%import svn_string.swg +%import svn_delta.i + +/* bad pool convention, also these should not be public interface at all + as commented by sussman. */ +%ignore svn_ra_svn_init; +%ignore svn_ra_local_init; +%ignore svn_ra_dav_init; + +/* ----------------------------------------------------------------------- + %apply-ing of typemaps defined elsewhere +*/ +%apply SWIGTYPE **OUTPARAM { + svn_ra_plugin_t **, + svn_ra_session_t **, + const svn_ra_reporter2_t **reporter, + void **report_baton, + svn_dirent_t **dirent, + svn_lock_t **lock, + const svn_delta_editor_t ** +}; + +%apply apr_hash_t **PROPHASH { apr_hash_t **props }; +%apply apr_hash_t **DIRENTHASH { apr_hash_t **dirents }; + +%apply const char *MAY_BE_NULL { + const char *comment, + const char *lock_token +}; + +%apply apr_hash_t *STRING_TO_STRING { + apr_hash_t *lock_tokens, + apr_hash_t *path_tokens +}; + +#ifdef SWIGPYTHON +%apply svn_stream_t *WRAPPED_STREAM { svn_stream_t * }; +#endif + +/* ----------------------------------------------------------------------- + handle svn_ra_get_locations() +*/ +%typemap(python,in) apr_array_header_t *location_revisions { + $1 = (apr_array_header_t *) svn_swig_py_revnums_to_array($input, + _global_pool); + if ($1 == NULL) + SWIG_fail; +} +%typemap(python,in,numinputs=0) apr_hash_t **locations = apr_hash_t **OUTPUT; +%typemap(python,argout,fragment="t_output_helper") apr_hash_t **locations { + $result = t_output_helper($result, svn_swig_py_locationhash_to_dict(*$1)); +} + +/* ----------------------------------------------------------------------- + thunk ra_callback +*/ +%apply const char **OUTPUT { + const char **url, + const char **uuid +}; + +%apply const apr_array_header_t *STRINGLIST { + const apr_array_header_t *paths +}; + +%typemap(perl5, in) (const svn_delta_editor_t *update_editor, + void *update_baton) { + svn_delta_make_editor(&$1, &$2, $input, _global_pool); +} +%typemap(perl5, in) (const svn_delta_editor_t *diff_editor, + void *diff_baton) { + svn_delta_make_editor(&$1, &$2, $input, _global_pool); +} + +%typemap(perl5, in) (const svn_ra_callbacks_t *callbacks, + void *callback_baton) { + svn_ra_make_callbacks(&$1, &$2, $input, _global_pool); +} + +%typemap(ruby, in) (const svn_ra_callbacks2_t *callbacks, + void *callback_baton) +{ + svn_swig_rb_setup_ra_callbacks(&$1, &$2, $input, _global_pool); +} + +%typemap(python, in) (const svn_ra_callbacks2_t *callbacks, + void *callback_baton) { + svn_swig_py_setup_ra_callbacks(&$1, &$2, $input, _global_pool); +} + +%typemap(python, in) (const svn_ra_callbacks2_t *callbacks, + void *callback_baton) { + svn_swig_py_setup_ra_callbacks(&$1, &$2, $input, _global_pool); +} + +%typemap(perl5, in) apr_hash_t *config { + $1 = svn_swig_pl_objs_to_hash_by_name ($input, "svn_config_t *", + _global_pool); +} + +%typemap(ruby, in) (svn_ra_lock_callback_t lock_func, void *lock_baton) +{ + $1 = svn_swig_rb_ra_lock_callback; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +%typemap(ruby, in) (svn_ra_file_rev_handler_t handler, void *handler_baton) +{ + $1 = svn_swig_rb_ra_file_rev_handler; + $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); +} + +%typemap(ruby, in) apr_hash_t *path_revs +{ + $1 = svn_swig_rb_hash_to_apr_hash_revnum($input, _global_pool); +} + +#ifdef SWIGPYTHON +%typemap(in) (svn_ra_file_rev_handler_t handler, void *handler_baton) +{ + $1 = svn_swig_py_ra_file_rev_handler_func; + $2 = (void *)$input; +} +#endif + +#ifdef SWIGPYTHON +%typemap(in) (const svn_ra_reporter2_t *reporter, void *report_baton) +{ + $1 = (svn_ra_reporter2_t *)&swig_py_ra_reporter2; + $2 = (void *)$input; +} +#endif + +/* ----------------------------------------------------------------------- */ + +%{ +#ifdef SWIGPYTHON +#include "swigutil_py.h" +#endif + +#ifdef SWIGPERL +#include "swigutil_pl.h" +#endif + +#ifdef SWIGRUBY +#include "swigutil_rb.h" +#endif +%} + +%include svn_ra_h.swg + diff -Nur subversion-1.3.1/subversion/bindings/swig/svn_ra.i.rej subversion-1.3.1.new/subversion/bindings/swig/svn_ra.i.rej --- subversion-1.3.1/subversion/bindings/swig/svn_ra.i.rej 1970-01-01 01:00:00.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/svn_ra.i.rej 2006-07-05 01:05:43.000000000 +0100 @@ -0,0 +1,17 @@ +*************** +*** 111,117 **** + #endif + + #ifdef SWIGPYTHON +- %typemap(in) (svn_ra_callbacks2_t *callbacks, + void *callback_baton) { + svn_swig_py_setup_ra_callbacks(&$1, &$2, $input, _global_pool); + } +--- 111,117 ---- + #endif + + #ifdef SWIGPYTHON ++ %typemap(in) (const svn_ra_callbacks2_t *callbacks, + void *callback_baton) { + svn_swig_py_setup_ra_callbacks(&$1, &$2, $input, _global_pool); + } diff -Nur subversion-1.3.1/subversion/bindings/swig/svn_wc.i subversion-1.3.1.new/subversion/bindings/swig/svn_wc.i --- subversion-1.3.1/subversion/bindings/swig/svn_wc.i 2005-10-20 23:10:56.000000000 +0100 +++ subversion-1.3.1.new/subversion/bindings/swig/svn_wc.i 2006-07-05 01:04:06.000000000 +0100 @@ -191,6 +191,20 @@ $1 = svn_swig_rb_array_to_apr_array_prop($input, pool); } +#ifdef SWIGPYTHON +%typemap(in, numinputs=0) + apr_array_header_t **patterns (apr_array_header_t *temp) +{ + $1 = &temp; +} +%typemap(argout, fragment="t_output_helper") + apr_array_header_t **patterns +{ + $result = t_output_helper($result, + svn_swig_py_array_to_list(*$1)); +} +#endif + /* ----------------------------------------------------------------------- Callback: svn_wc_notify_func_t svn_client_ctx_t @@ -237,6 +251,11 @@ $2 = $input; /* our function is the baton. */ } +%typemap(python,in) (svn_wc_notify_func2_t notify_func, void *notify_baton) { + $1 = svn_swig_py_notify_func2; + $2 = $input; /* our function is the baton. */ +} + %typemap(perl5,in) (svn_wc_status_func_t status_func, void *status_baton) { $1 = svn_swig_pl_status_func; $2 = $input; /* our function is the baton. */ diff -Nur subversion-1.3.1/subversion/libsvn_ra_svn/client.c subversion-1.3.1.new/subversion/libsvn_ra_svn/client.c --- subversion-1.3.1/subversion/libsvn_ra_svn/client.c 2005-12-09 01:55:09.000000000 +0000 +++ subversion-1.3.1.new/subversion/libsvn_ra_svn/client.c 2006-07-05 01:04:06.000000000 +0100 @@ -1151,11 +1151,8 @@ } apr_pool_destroy(subpool); - if (nreceived <= limit) - { - /* Read the response. */ - SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "")); - } + /* Read the response. */ + SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "")); return SVN_NO_ERROR; } diff -Nur subversion-1.3.1/subversion/libsvn_subr/constructors.c subversion-1.3.1.new/subversion/libsvn_subr/constructors.c --- subversion-1.3.1/subversion/libsvn_subr/constructors.c 2005-10-18 19:40:02.000000000 +0100 +++ subversion-1.3.1.new/subversion/libsvn_subr/constructors.c 2006-07-05 01:04:06.000000000 +0100 @@ -36,6 +36,23 @@ return commit_info; } +svn_commit_info_t * +svn_commit_info_dup(const svn_commit_info_t *src_commit_info, + apr_pool_t *pool) +{ + svn_commit_info_t *dst_commit_info = svn_create_commit_info(pool); + + dst_commit_info->date = src_commit_info->date + ? apr_pstrdup(pool, src_commit_info->date) : NULL; + dst_commit_info->author = src_commit_info->author + ? apr_pstrdup(pool, src_commit_info->author) : NULL; + dst_commit_info->revision = src_commit_info->revision; + dst_commit_info->post_commit_err = src_commit_info->post_commit_err + ? apr_pstrdup(pool, src_commit_info->post_commit_err) : NULL; + + return dst_commit_info; +} + svn_log_changed_path_t * svn_log_changed_path_dup (const svn_log_changed_path_t *changed_path, apr_pool_t *pool)