Index: ./build.conf
===================================================================
--- ./build.conf
+++ ./build.conf	Sat Aug 31 16:13:14 2002
@@ -197,7 +197,7 @@
 type = lib
 path = subversion/bindings/swig
 sources = swigutil_py.c
-libs = $(SVN_APRUTIL_LIBS) $(SVN_APR_LIBS)
+libs = libsvn_client libsvn_repos $(SVN_APRUTIL_LIBS) $(SVN_APR_LIBS)
 install = swig-py-lib
 # need special build rule to include -DSWIGPYTHON
 custom = swig-py
Index: ./subversion/include/svn_error_codes.h
===================================================================
--- ./subversion/include/svn_error_codes.h
+++ ./subversion/include/svn_error_codes.h	Sat Aug 31 15:55:19 2002
@@ -639,6 +639,10 @@
               SVN_ERR_MISC_CATEGORY_START + 12,
               "Error calling external program")
 
+  SVN_ERRDEF (SVN_ERR_SWIG_PY_EXCEPTION_SET,
+              SVN_ERR_MISC_CATEGORY_START + 13,
+              "Python exception has been set with the error")
+
   /* command-line client errors */
 
   SVN_ERRDEF (SVN_ERR_CL_ARG_PARSING_ERROR,
Index: ./subversion/bindings/swig/svn_types.i
===================================================================
--- ./subversion/bindings/swig/svn_types.i
+++ ./subversion/bindings/swig/svn_types.i	Sat Aug 31 15:58:44 2002
@@ -51,12 +51,15 @@
     $1 = copied;
 }
 
-/* ----------------------------------------------------------------------- */
+/* -----------------------------------------------------------------------
+   Specify how svn_error_t returns are turned into exceptions.
+*/
 
 %typemap(python,out) svn_error_t * {
     if ($1 != NULL) {
-        PyErr_SetString(PyExc_RuntimeError,
-                        $1->message ? $1->message : "unknown error");
+        if ($1->apr_err != SVN_ERR_SWIG_PY_EXCEPTION_SET)
+            PyErr_SetString(PyExc_RuntimeError,
+                            $1->message ? $1->message : "unknown error");
         return NULL;
     }
     Py_INCREF(Py_None);
Index: ./subversion/bindings/swig/svn_string.i
===================================================================
--- ./subversion/bindings/swig/svn_string.i
+++ ./subversion/bindings/swig/svn_string.i	Sat Aug 31 16:07:15 2002
@@ -130,15 +130,4 @@
     $result = t_output_helper($result, s);
 }
 
-/* -----------------------------------------------------------------------
-   define a general INPUT param of an array of svn_stringbuf_t* items.
- */
-
-%typemap(python,in) const apr_array_header_t *STRINGLIST {
-%#error need pool argument from somewhere
-    $1 = svn_swig_py_strings_to_array($input, NULL);
-    if ($1 == NULL)
-        return NULL;
-}
-
 /* ----------------------------------------------------------------------- */
Index: ./subversion/bindings/swig/svn_client.i
===================================================================
--- ./subversion/bindings/swig/svn_client.i
+++ ./subversion/bindings/swig/svn_client.i	Sat Aug 31 16:54:38 2002
@@ -29,21 +29,6 @@
 */
 %ignore svn_client_proplist_item_s;
 
-/* ### these take an 'apr_array_header_t *' which requires a pool, which
-   ### we don't have immediately handy. just eliminate these funcs for now. */
-%ignore svn_client_commit;
-%ignore svn_client_log;
-%ignore svn_client_diff;
-
-/* -----------------------------------------------------------------------
-   all "targets" and "diff_options" arrays are constant inputs of
-   svn_stringbuf_t *
- */
-%apply const apr_array_header_t *STRINGLIST {
-    const apr_array_header_t *targets,
-    const apr_array_header_t *diff_options
-};
-
 /* -----------------------------------------------------------------------
    fix up the return hash for svn_client_propget()
 */
@@ -102,6 +87,23 @@
 */
 %types(svn_wc_status_t *);
 
+/* -----------------------------------------------------------------------
+   The following functions need special handling because they have a
+   parameter which is an apr_array_header_t. We have a special wrapper
+   which takes a PyObject *. That wrapper will convert the Python
+   sequence into an APR array and call the real function.
+*/
+%ignore svn_client_commit;
+%ignore svn_client_log;
+%ignore svn_client_diff;
+
+%rename(svn_client_commit) svn_swig_py_client_commit;
+%rename(svn_client_log) svn_swig_py_client_log;
+%rename(svn_client_diff) svn_swig_py_client_diff;
+
+#define SVN_SWIG_ONLY_CLIENT_FUNCS
+%include swig_workarounds.h
+
 /* ----------------------------------------------------------------------- */
 
 /* Include the headers before we swig-include the svn_client.h header file.
@@ -111,6 +113,9 @@
 %header %{
 #include "svn_client.h"
 
+#define SVN_SWIG_ONLY_CLIENT_FUNCS
+#include "swig_workarounds.h"
+
 #ifdef SWIGPYTHON
 #include "swigutil_py.h"
 #endif
Index: ./subversion/bindings/swig/swig_workarounds.h
===================================================================
--- ./subversion/bindings/swig/swig_workarounds.h
+++ ./subversion/bindings/swig/swig_workarounds.h	Sat Aug 31 17:06:20 2002
@@ -0,0 +1,147 @@
+/*
+ * swig_workarounds.h : this file defines special workaround functions to
+ *                      enable wrapping certain SVN functions.
+ *
+ * ====================================================================
+ * Copyright (c) 2000-2002 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_WORKAROUNDS_H
+#define SVN_SWIG_WORKAROUNDS_H
+
+
+#ifdef SWIGPYTHON
+
+#include <Python.h>
+
+#define SVN_SWIG_NATIVE_ARRAY PyObject *
+
+#else
+#error Unknown environment for definition of workarounds
+#endif
+
+
+#include "svn_client.h"
+#include "svn_repos.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef SVN_SWIG_ALL_WORKAROUNDS
+#define SVN_SWIG_ONLY_CLIENT_FUNCS
+#define SVN_SWIG_ONLY_REPOS_FUNCS
+#endif
+
+/* the following functions are exactly like their counterparts in the
+   SVN library, except that apr_array_header_t* parameters are Python
+   objects. We will wrap these functions (accepting Python objects),
+   convert that object to an APR array, then call the normal SVN
+   function.  */
+
+/* NOTE: it would have been really cool to use some preprocessor magic
+   in here to simplify the declaration of the various wrappers on a per
+   language basis, but it seems the SWIG preprocessor isn't getting quite
+   the right substituations at the expected time. So... we gotta do it
+   the long way. Rather than repeat the parameters a billion times, we
+   simply define them once, and use them over and over.  */
+
+/* parameters for svn_client_commit */
+#define SVN_SWIG_PARAMS_CLIENT_COMMIT (         \
+    svn_client_commit_info_t **commit_info,     \
+    svn_wc_notify_func_t notify_func,           \
+    void *notify_baton,                         \
+    svn_client_auth_baton_t *auth_baton,        \
+    SVN_SWIG_NATIVE_ARRAY targets,              \
+    svn_client_get_commit_log_t log_msg_func,   \
+    void *log_msg_baton,                        \
+    const char *xml_dst,                        \
+    svn_revnum_t revision,                      \
+    svn_boolean_t nonrecursive,                 \
+    apr_pool_t *pool                            \
+    )
+
+/* parameters for svn_client_log */
+#define SVN_SWIG_PARAMS_CLIENT_LOG (            \
+    svn_client_auth_baton_t *auth_baton,        \
+    SVN_SWIG_NATIVE_ARRAY targets,              \
+    const svn_client_revision_t *start,         \
+    const svn_client_revision_t *end,           \
+    svn_boolean_t discover_changed_paths,       \
+    svn_boolean_t strict_node_history,          \
+    svn_log_message_receiver_t receiver,        \
+    void *receiver_baton,                       \
+    apr_pool_t *pool                            \
+    )
+
+/* parameters for svn_client_diff */
+#define SVN_SWIG_PARAMS_CLIENT_DIFF (           \
+    SVN_SWIG_NATIVE_ARRAY diff_options,         \
+    svn_client_auth_baton_t *auth_baton,        \
+    const char *path1,                          \
+    const svn_client_revision_t *revision1,     \
+    const char *path2,                          \
+    const svn_client_revision_t *revision2,     \
+    svn_boolean_t recurse,                      \
+    apr_file_t *outfile,                        \
+    apr_file_t *errfile,                        \
+    apr_pool_t *pool                            \
+    )
+
+/* parameters for svn_repos_get_logs */
+#define SVN_SWIG_PARAMS_REPOS_GET_LOGS (        \
+    svn_repos_t *repos,                         \
+    SVN_SWIG_NATIVE_ARRAY paths,                \
+    svn_revnum_t start,                         \
+    svn_revnum_t end,                           \
+    svn_boolean_t discover_changed_paths,       \
+    svn_boolean_t strict_node_history,          \
+    svn_log_message_receiver_t receiver,        \
+    void *receiver_baton,                       \
+    apr_pool_t *pool                            \
+    )
+
+
+#ifdef SVN_SWIG_ONLY_CLIENT_FUNCS
+
+#ifdef SWIGPYTHON
+svn_error_t * svn_swig_py_client_commit SVN_SWIG_PARAMS_CLIENT_COMMIT;
+svn_error_t * svn_swig_py_client_log SVN_SWIG_PARAMS_CLIENT_LOG;
+svn_error_t * svn_swig_py_client_diff SVN_SWIG_PARAMS_CLIENT_DIFF;
+#endif
+
+#endif /* SVN_SWIG_ONLY_CLIENT_FUNCS */
+
+#ifdef SVN_SWIG_ONLY_REPOS_FUNCS
+
+#ifdef SWIGPYTHON
+svn_error_t * svn_swig_py_repos_get_logs SVN_SWIG_PARAMS_REPOS_GET_LOGS;
+#endif
+
+#endif /* SVN_SWIG_ONLY_REPOS_FUNCS */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SVN_SWIG_WORKAROUNDS_H */
+
+
+/* ----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../../tools/dev/svn-dev.el")
+ * end:
+ */
Index: ./subversion/bindings/swig/swigutil_py.c
===================================================================
--- ./subversion/bindings/swig/swigutil_py.c
+++ ./subversion/bindings/swig/swigutil_py.c	Sat Aug 31 17:06:48 2002
@@ -25,6 +25,9 @@
 #include "svn_string.h"
 #include "svn_delta.h"
 
+#define SVN_SWIG_ALL_WORKAROUNDS
+#include "swig_workarounds.h"
+
 #include "swigutil_py.h"
 
 
@@ -166,31 +169,44 @@
     return NULL;
 }
 
-const apr_array_header_t *svn_swig_py_strings_to_array(PyObject *source,
-                                                       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.  */
+static svn_error_t *convert_to_array(const apr_array_header_t **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;
+        goto error;
     }
     targlen = PySequence_Length(source);
     temp = apr_array_make(pool, targlen, sizeof(const char *));
     while (targlen--) {
         PyObject *o = PySequence_GetItem(source, targlen);
         if (o == NULL)
-            return NULL;
+            goto error;
         if (!PyString_Check(o)) {
             Py_DECREF(o);
-            PyErr_SetString(PyExc_TypeError, "not a sequence");
-            return NULL;
+            PyErr_SetString(PyExc_TypeError, "sequence contains a non-string");
+            goto error;
         }
         APR_ARRAY_IDX(temp, targlen, const char *) = PyString_AS_STRING(o);
         Py_DECREF(o);
     }
-    return temp;
+
+    *array = temp;
+    return NULL;
+
+ error:
+    return svn_error_create(SVN_ERR_SWIG_PY_EXCEPTION_SET, 0, NULL,
+                            pool, "A Python exception was raised");
 }
 
 
@@ -575,6 +591,68 @@
   *edit_baton = make_baton(pool, py_editor, NULL);
 }
 
+
+svn_error_t * svn_swig_py_client_commit SVN_SWIG_PARAMS_CLIENT_COMMIT
+{
+  const apr_array_header_t *array;
+
+  SVN_ERR( convert_to_array(&array, targets, pool) );
+
+  return svn_client_commit(commit_info,
+                           notify_func, notify_baton,
+                           auth_baton,
+                           array,
+                           log_msg_func, log_msg_baton,
+                           xml_dst,
+                           revision,
+                           nonrecursive,
+                           pool);
+}
+
+svn_error_t * svn_swig_py_client_log SVN_SWIG_PARAMS_CLIENT_LOG
+{
+  const apr_array_header_t *array;
+
+  SVN_ERR( convert_to_array(&array, targets, pool) );
+
+  return svn_client_log(auth_baton,
+                        array,
+                        start, end,
+                        discover_changed_paths, strict_node_history,
+                        receiver, receiver_baton,
+                        pool);
+}
+
+svn_error_t *svn_swig_py_client_diff SVN_SWIG_PARAMS_CLIENT_DIFF
+{
+  const apr_array_header_t *array;
+
+  SVN_ERR( convert_to_array(&array, diff_options, pool) );
+
+  return svn_client_diff(array, auth_baton,
+                         path1, revision1,
+                         path2, revision2,
+                         recurse,
+                         outfile, errfile,
+                         pool);
+}
+
+svn_error_t * svn_swig_py_repos_get_logs SVN_SWIG_PARAMS_REPOS_GET_LOGS
+{
+  const apr_array_header_t *array;
+
+  SVN_ERR( convert_to_array(&array, paths, pool) );
+
+  return svn_repos_get_logs(repos,
+                            array,
+                            start, end,
+                            discover_changed_paths,
+                            strict_node_history,
+                            receiver, receiver_baton,
+                            pool);
+}
+
+
 /* ----------------------------------------------------------------
  * local variables:
  * eval: (load-file "../../../tools/dev/svn-dev.el")
Index: ./subversion/bindings/swig/svn_repos.i
===================================================================
--- ./subversion/bindings/swig/svn_repos.i
+++ ./subversion/bindings/swig/svn_repos.i	Sat Aug 31 16:55:45 2002
@@ -24,10 +24,6 @@
 %import svn_string.i
 %import svn_fs.i
 
-/* ### we need access to the pool arg to properly handle svn_repos_get_logs.
-   ### for now, just disable it.
-*/
-%ignore svn_repos_get_logs;
 
 /* -----------------------------------------------------------------------
    these types (as 'type **') will always be an OUT param
@@ -37,11 +33,16 @@
 };
 
 /* -----------------------------------------------------------------------
-   handle the 'paths' parameter appropriately
+   svn_repos_get_logs() needs special handling because of its 'paths'
+   parameter, which is an apr_array_header_t. We have a special wrapper
+   which takes a PyObject *. That wrapper will convert the Python
+   sequence into an APR array and call the real function.
 */
-%apply const apr_array_header_t *STRINGLIST {
-    const apr_array_header_t *paths
-};
+%ignore svn_repos_get_logs;
+%rename(svn_repos_get_logs) svn_swig_py_repos_get_logs;
+
+#define SVN_SWIG_ONLY_REPOS_FUNCS
+%include swig_workarounds.h
 
 /* -----------------------------------------------------------------------
    dir_delta's src_entry parameter needs to be NULL sometimes
@@ -54,6 +55,9 @@
 %{
 #include "svn_repos.h"
 
+#define SVN_SWIG_ONLY_REPOS_FUNCS
+#include "swig_workarounds.h"
+
 #ifdef SWIGPYTHON
 #include "swigutil_py.h"
 #endif
Index: ./subversion/bindings/swig/swigutil_py.h
===================================================================
--- ./subversion/bindings/swig/swigutil_py.h
+++ ./subversion/bindings/swig/swigutil_py.h	Sat Aug 31 16:58:07 2002
@@ -31,6 +31,8 @@
 #include "svn_types.h"
 #include "svn_string.h"
 #include "svn_delta.h"
+#include "svn_client.h"
+#include "svn_repos.h"
 
 
 #ifdef __cplusplus
@@ -71,20 +73,13 @@
    of string objects */
 PyObject *svn_swig_py_array_to_list(const apr_array_header_t *strings);
 
-/* 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.  */
-const apr_array_header_t *svn_swig_py_strings_to_array(PyObject *source,
-                                                       apr_pool_t *pool);
-
 /* make a editor that "thunks" from C callbacks up to Python */
 void svn_swig_py_make_editor(const svn_delta_editor_t **editor,
                              void **edit_baton,
                              PyObject *py_editor,
                              apr_pool_t *pool);
 
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */


